Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4357 → Rev 4358

/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/dri2.c
0,0 → 1,0
../../../../glx/dri2.c
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/glcore.h
0,0 → 1,181
#ifndef __gl_core_h_
#define __gl_core_h_
 
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. 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 including the dates of first publication and
* either this permission notice or a reference to
* http://oss.sgi.com/projects/FreeB/
* 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
* SILICON GRAPHICS, INC. 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.
*
* Except as contained in this notice, the name of Silicon Graphics, Inc.
* shall not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization from
* Silicon Graphics, Inc.
*/
 
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#endif
 
#define GL_CORE_SGI 1
#define GL_CORE_MESA 2
#define GL_CORE_APPLE 4
#define GL_CORE_WINDOWS 8
 
typedef struct __GLcontextRec __GLcontext;
 
/*
** This file defines the interface between the GL core and the surrounding
** "operating system" that supports it (currently the GLX or WGL extensions).
**
** Members (data and function pointers) are documented as imported or
** exported according to how they are used by the core rendering functions.
** Imported members are initialized by the "operating system" and used by
** the core functions. Exported members are initialized by the core functions
** and used by the "operating system".
*/
 
/**
* Mode and limit information for a context. This information is
* kept around in the context so that values can be used during
* command execution, and for returning information about the
* context to the application.
*
* Instances of this structure are shared by the driver and the loader. To
* maintain binary compatability, new fields \b must be added only to the
* end of the structure.
*
* \sa _gl_context_modes_create
*/
typedef struct __GLcontextModesRec {
struct __GLcontextModesRec * next;
 
GLboolean rgbMode;
GLboolean floatMode;
GLboolean colorIndexMode;
GLuint doubleBufferMode;
GLuint stereoMode;
 
GLboolean haveAccumBuffer;
GLboolean haveDepthBuffer;
GLboolean haveStencilBuffer;
 
GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
GLuint redMask, greenMask, blueMask, alphaMask;
GLint rgbBits; /* total bits for rgb */
GLint indexBits; /* total bits for colorindex */
 
GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
GLint depthBits;
GLint stencilBits;
 
GLint numAuxBuffers;
 
GLint level;
 
GLint pixmapMode;
 
/* GLX */
GLint visualID;
GLint visualType; /**< One of the GLX X visual types. (i.e.,
* \c GLX_TRUE_COLOR, etc.)
*/
 
/* EXT_visual_rating / GLX 1.2 */
GLint visualRating;
 
/* EXT_visual_info / GLX 1.2 */
GLint transparentPixel;
/* colors are floats scaled to ints */
GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
GLint transparentIndex;
 
/* ARB_multisample / SGIS_multisample */
GLint sampleBuffers;
GLint samples;
 
/* SGIX_fbconfig / GLX 1.3 */
GLint drawableType;
GLint renderType;
GLint xRenderable;
GLint fbconfigID;
 
/* SGIX_pbuffer / GLX 1.3 */
GLint maxPbufferWidth;
GLint maxPbufferHeight;
GLint maxPbufferPixels;
GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
 
/* SGIX_visual_select_group */
GLint visualSelectGroup;
 
/* OML_swap_method */
GLint swapMethod;
 
GLint screen;
 
/* EXT_texture_from_pixmap */
GLint bindToTextureRgb;
GLint bindToTextureRgba;
GLint bindToMipmapTexture;
GLint bindToTextureTargets;
GLint yInverted;
} __GLcontextModes;
 
/* Several fields of __GLcontextModes can take these as values. Since
* GLX header files may not be available everywhere they need to be used,
* redefine them here.
*/
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_PSEUDO_COLOR 0x8004
#define GLX_STATIC_COLOR 0x8005
#define GLX_GRAY_SCALE 0x8006
#define GLX_STATIC_GRAY 0x8007
#define GLX_TRANSPARENT_RGB 0x8008
#define GLX_TRANSPARENT_INDEX 0x8009
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_SWAP_EXCHANGE_OML 0x8061
#define GLX_SWAP_COPY_OML 0x8062
#define GLX_SWAP_UNDEFINED_OML 0x8063
 
#define GLX_DONT_CARE 0xFFFFFFFF
 
#define GLX_RGBA_BIT 0x00000001
#define GLX_COLOR_INDEX_BIT 0x00000002
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
 
#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
#define GLX_Y_INVERTED_EXT 0x20D4
 
#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
 
#endif /* __gl_core_h_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/glxinit.c
0,0 → 1,656
/**
* GLX initialization. Code based on glxext.c, glx_query.c, and
* glcontextmodes.c under src/glx/. The major difference is that DRI
* related code is stripped out.
*
* If the maintenance of this file takes too much time, we should consider
* refactoring glxext.c.
*/
 
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/Xproto.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <sys/time.h>
 
#include "GL/glxproto.h"
#include "GL/glxtokens.h"
#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
#include "glcore.h" /* for __GLcontextModes */
 
#include "glxinit.h"
 
#ifdef GLX_DIRECT_RENDERING
 
typedef struct GLXGenericGetString
{
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
} xGLXGenericGetStringReq;
 
#define sz_xGLXGenericGetStringReq 12
#define X_GLXGenericGetString 0
 
/* Extension required boiler plate */
 
static char *__glXExtensionName = GLX_EXTENSION_NAME;
static XExtensionInfo *__glXExtensionInfo = NULL;
 
static int
__glXCloseDisplay(Display * dpy, XExtCodes * codes)
{
return XextRemoveDisplay(__glXExtensionInfo, dpy);
}
 
static /* const */ XExtensionHooks __glXExtensionHooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
__glXCloseDisplay, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
 
static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
__glXExtensionName, &__glXExtensionHooks,
__GLX_NUMBER_EVENTS, NULL)
 
static GLint
_gl_convert_from_x_visual_type(int visualType)
{
#define NUM_VISUAL_TYPES 6
static const int glx_visual_types[NUM_VISUAL_TYPES] = {
GLX_STATIC_GRAY, GLX_GRAY_SCALE,
GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
GLX_TRUE_COLOR, GLX_DIRECT_COLOR
};
 
return ((unsigned) visualType < NUM_VISUAL_TYPES)
? glx_visual_types[visualType] : GLX_NONE;
}
 
static void
_gl_context_modes_destroy(__GLcontextModes * modes)
{
while (modes != NULL) {
__GLcontextModes *const next = modes->next;
 
free(modes);
modes = next;
}
}
 
static __GLcontextModes *
_gl_context_modes_create(unsigned count, size_t minimum_size)
{
const size_t size = (minimum_size > sizeof(__GLcontextModes))
? minimum_size : sizeof(__GLcontextModes);
__GLcontextModes *base = NULL;
__GLcontextModes **next;
unsigned i;
 
next = &base;
for (i = 0; i < count; i++) {
*next = malloc(size);
if (*next == NULL) {
_gl_context_modes_destroy(base);
base = NULL;
break;
}
 
memset(*next, 0, size);
(*next)->visualID = GLX_DONT_CARE;
(*next)->visualType = GLX_DONT_CARE;
(*next)->visualRating = GLX_NONE;
(*next)->transparentPixel = GLX_NONE;
(*next)->transparentRed = GLX_DONT_CARE;
(*next)->transparentGreen = GLX_DONT_CARE;
(*next)->transparentBlue = GLX_DONT_CARE;
(*next)->transparentAlpha = GLX_DONT_CARE;
(*next)->transparentIndex = GLX_DONT_CARE;
(*next)->xRenderable = GLX_DONT_CARE;
(*next)->fbconfigID = GLX_DONT_CARE;
(*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
(*next)->bindToTextureRgb = GLX_DONT_CARE;
(*next)->bindToTextureRgba = GLX_DONT_CARE;
(*next)->bindToMipmapTexture = GLX_DONT_CARE;
(*next)->bindToTextureTargets = GLX_DONT_CARE;
(*next)->yInverted = GLX_DONT_CARE;
 
next = &((*next)->next);
}
 
return base;
}
 
static char *
__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
{
xGLXGenericGetStringReq *req;
xGLXSingleReply reply;
int length;
int numbytes;
char *buf;
CARD32 for_whom = screen;
CARD32 glxCode = X_GLXQueryServerString;
 
 
LockDisplay(dpy);
 
 
/* All of the GLX protocol requests for getting a string from the server
* look the same. The exact meaning of the for_whom field is usually
* either the screen number (for glXQueryServerString) or the context tag
* (for GLXSingle).
*/
 
GetReq(GLXGenericGetString, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->for_whom = for_whom;
req->name = name;
 
_XReply(dpy, (xReply *) & reply, 0, False);
 
length = reply.length * 4;
numbytes = reply.size;
 
buf = malloc(numbytes);
if (buf != NULL) {
_XRead(dpy, buf, numbytes);
length -= numbytes;
}
 
_XEatData(dpy, length);
 
UnlockDisplay(dpy);
SyncHandle();
 
return buf;
}
 
/************************************************************************/
/*
** Free the per screen configs data as well as the array of
** __glXScreenConfigs.
*/
static void
FreeScreenConfigs(__GLXdisplayPrivate * priv)
{
__GLXscreenConfigs *psc;
GLint i, screens;
 
/* Free screen configuration information */
screens = ScreenCount(priv->dpy);
for (i = 0; i < screens; i++) {
psc = priv->screenConfigs[i];
if (!psc)
continue;
if (psc->configs) {
_gl_context_modes_destroy(psc->configs);
psc->configs = NULL; /* NOTE: just for paranoia */
}
free((char *) psc->serverGLXexts);
}
free((char *) priv->screenConfigs);
priv->screenConfigs = NULL;
}
 
/*
** Release the private memory referred to in a display private
** structure. The caller will free the extension structure.
*/
static int
__glXFreeDisplayPrivate(XExtData * extension)
{
__GLXdisplayPrivate *priv;
 
priv = (__GLXdisplayPrivate *) extension->private_data;
FreeScreenConfigs(priv);
free((char *) priv->serverGLXversion);
free((char *) priv);
return 0;
}
 
/************************************************************************/
 
/*
** Query the version of the GLX extension. This procedure works even if
** the client extension is not completely set up.
*/
 
#define GLX_MAJOR_VERSION 1 /* current version numbers */
#define GLX_MINOR_VERSION 4
 
static Bool
QueryVersion(Display * dpy, int opcode, int *major, int *minor)
{
xGLXQueryVersionReq *req;
xGLXQueryVersionReply reply;
 
/* Send the glXQueryVersion request */
LockDisplay(dpy);
GetReq(GLXQueryVersion, req);
req->reqType = opcode;
req->glxCode = X_GLXQueryVersion;
req->majorVersion = GLX_MAJOR_VERSION;
req->minorVersion = GLX_MINOR_VERSION;
_XReply(dpy, (xReply *) & reply, 0, False);
UnlockDisplay(dpy);
SyncHandle();
 
if (reply.majorVersion != GLX_MAJOR_VERSION) {
/*
** The server does not support the same major release as this
** client.
*/
return GL_FALSE;
}
*major = reply.majorVersion;
*minor = min(reply.minorVersion, GLX_MINOR_VERSION);
return GL_TRUE;
}
 
#define __GLX_MIN_CONFIG_PROPS 18
#define __GLX_MAX_CONFIG_PROPS 500
#define __GLX_EXT_CONFIG_PROPS 10
#define __GLX_TOTAL_CONFIG (__GLX_MIN_CONFIG_PROPS + \
2 * __GLX_EXT_CONFIG_PROPS)
 
static void
__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
const INT32 * bp, Bool tagged_only,
Bool fbconfig_style_tags)
{
int i;
 
if (!tagged_only) {
/* Copy in the first set of properties */
config->visualID = *bp++;
 
config->visualType = _gl_convert_from_x_visual_type(*bp++);
 
config->rgbMode = *bp++;
 
config->redBits = *bp++;
config->greenBits = *bp++;
config->blueBits = *bp++;
config->alphaBits = *bp++;
config->accumRedBits = *bp++;
config->accumGreenBits = *bp++;
config->accumBlueBits = *bp++;
config->accumAlphaBits = *bp++;
 
config->doubleBufferMode = *bp++;
config->stereoMode = *bp++;
 
config->rgbBits = *bp++;
config->depthBits = *bp++;
config->stencilBits = *bp++;
config->numAuxBuffers = *bp++;
config->level = *bp++;
 
count -= __GLX_MIN_CONFIG_PROPS;
}
 
/*
** Additional properties may be in a list at the end
** of the reply. They are in pairs of property type
** and property value.
*/
 
#define FETCH_OR_SET(tag) \
config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
 
for (i = 0; i < count; i += 2) {
switch (*bp++) {
case GLX_RGBA:
FETCH_OR_SET(rgbMode);
break;
case GLX_BUFFER_SIZE:
config->rgbBits = *bp++;
break;
case GLX_LEVEL:
config->level = *bp++;
break;
case GLX_DOUBLEBUFFER:
FETCH_OR_SET(doubleBufferMode);
break;
case GLX_STEREO:
FETCH_OR_SET(stereoMode);
break;
case GLX_AUX_BUFFERS:
config->numAuxBuffers = *bp++;
break;
case GLX_RED_SIZE:
config->redBits = *bp++;
break;
case GLX_GREEN_SIZE:
config->greenBits = *bp++;
break;
case GLX_BLUE_SIZE:
config->blueBits = *bp++;
break;
case GLX_ALPHA_SIZE:
config->alphaBits = *bp++;
break;
case GLX_DEPTH_SIZE:
config->depthBits = *bp++;
break;
case GLX_STENCIL_SIZE:
config->stencilBits = *bp++;
break;
case GLX_ACCUM_RED_SIZE:
config->accumRedBits = *bp++;
break;
case GLX_ACCUM_GREEN_SIZE:
config->accumGreenBits = *bp++;
break;
case GLX_ACCUM_BLUE_SIZE:
config->accumBlueBits = *bp++;
break;
case GLX_ACCUM_ALPHA_SIZE:
config->accumAlphaBits = *bp++;
break;
case GLX_VISUAL_CAVEAT_EXT:
config->visualRating = *bp++;
break;
case GLX_X_VISUAL_TYPE:
config->visualType = *bp++;
break;
case GLX_TRANSPARENT_TYPE:
config->transparentPixel = *bp++;
break;
case GLX_TRANSPARENT_INDEX_VALUE:
config->transparentIndex = *bp++;
break;
case GLX_TRANSPARENT_RED_VALUE:
config->transparentRed = *bp++;
break;
case GLX_TRANSPARENT_GREEN_VALUE:
config->transparentGreen = *bp++;
break;
case GLX_TRANSPARENT_BLUE_VALUE:
config->transparentBlue = *bp++;
break;
case GLX_TRANSPARENT_ALPHA_VALUE:
config->transparentAlpha = *bp++;
break;
case GLX_VISUAL_ID:
config->visualID = *bp++;
break;
case GLX_DRAWABLE_TYPE:
config->drawableType = *bp++;
break;
case GLX_RENDER_TYPE:
config->renderType = *bp++;
break;
case GLX_X_RENDERABLE:
config->xRenderable = *bp++;
break;
case GLX_FBCONFIG_ID:
config->fbconfigID = *bp++;
break;
case GLX_MAX_PBUFFER_WIDTH:
config->maxPbufferWidth = *bp++;
break;
case GLX_MAX_PBUFFER_HEIGHT:
config->maxPbufferHeight = *bp++;
break;
case GLX_MAX_PBUFFER_PIXELS:
config->maxPbufferPixels = *bp++;
break;
case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
config->optimalPbufferWidth = *bp++;
break;
case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
config->optimalPbufferHeight = *bp++;
break;
case GLX_VISUAL_SELECT_GROUP_SGIX:
config->visualSelectGroup = *bp++;
break;
case GLX_SWAP_METHOD_OML:
config->swapMethod = *bp++;
break;
case GLX_SAMPLE_BUFFERS_SGIS:
config->sampleBuffers = *bp++;
break;
case GLX_SAMPLES_SGIS:
config->samples = *bp++;
break;
case GLX_BIND_TO_TEXTURE_RGB_EXT:
config->bindToTextureRgb = *bp++;
break;
case GLX_BIND_TO_TEXTURE_RGBA_EXT:
config->bindToTextureRgba = *bp++;
break;
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
config->bindToMipmapTexture = *bp++;
break;
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
config->bindToTextureTargets = *bp++;
break;
case GLX_Y_INVERTED_EXT:
config->yInverted = *bp++;
break;
case None:
i = count;
break;
default:
break;
}
}
 
config->renderType =
(config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
 
config->haveAccumBuffer = ((config->accumRedBits +
config->accumGreenBits +
config->accumBlueBits +
config->accumAlphaBits) > 0);
config->haveDepthBuffer = (config->depthBits > 0);
config->haveStencilBuffer = (config->stencilBits > 0);
}
 
static __GLcontextModes *
createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
int screen, GLboolean tagged_only)
{
INT32 buf[__GLX_TOTAL_CONFIG], *props;
unsigned prop_size;
__GLcontextModes *modes, *m;
int i;
 
if (nprops == 0)
return NULL;
 
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
 
/* Check number of properties */
if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
return NULL;
 
/* Allocate memory for our config structure */
modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
if (!modes)
return NULL;
 
prop_size = nprops * __GLX_SIZE_INT32;
if (prop_size <= sizeof(buf))
props = buf;
else
props = malloc(prop_size);
 
/* Read each config structure and convert it into our format */
m = modes;
for (i = 0; i < nvisuals; i++) {
_XRead(dpy, (char *) props, prop_size);
/* Older X servers don't send this so we default it here. */
m->drawableType = GLX_WINDOW_BIT;
__glXInitializeVisualConfigFromTags(m, nprops, props,
tagged_only, GL_TRUE);
m->screen = screen;
m = m->next;
}
 
if (props != buf)
free(props);
 
return modes;
}
 
static GLboolean
getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
{
xGLXGetFBConfigsReq *fb_req;
xGLXGetFBConfigsSGIXReq *sgi_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXGetFBConfigsReply reply;
Display *dpy = priv->dpy;
 
psc->serverGLXexts =
__glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
 
LockDisplay(dpy);
 
psc->configs = NULL;
if (atof(priv->serverGLXversion) >= 1.3) {
GetReq(GLXGetFBConfigs, fb_req);
fb_req->reqType = priv->majorOpcode;
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = screen;
}
else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq +
sz_xGLXVendorPrivateWithReplyReq, vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = priv->majorOpcode;
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
sgi_req->screen = screen;
}
else
goto out;
 
if (!_XReply(dpy, (xReply *) & reply, 0, False))
goto out;
 
psc->configs = createConfigsFromProperties(dpy,
reply.numFBConfigs,
reply.numAttribs * 2,
screen, GL_TRUE);
 
out:
UnlockDisplay(dpy);
return psc->configs != NULL;
}
 
static GLboolean
AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
{
__GLXscreenConfigs *psc;
GLint i, screens;
 
/*
** First allocate memory for the array of per screen configs.
*/
screens = ScreenCount(dpy);
priv->screenConfigs = malloc(screens * sizeof *priv->screenConfigs);
if (!priv->screenConfigs) {
return GL_FALSE;
}
 
priv->serverGLXversion =
__glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
if (priv->serverGLXversion == NULL) {
FreeScreenConfigs(priv);
return GL_FALSE;
}
 
for (i = 0; i < screens; i++) {
psc = calloc(1, sizeof *psc);
if (!psc)
return GL_FALSE;
getFBConfigs(psc, priv, i);
priv->screenConfigs[i] = psc;
}
 
SyncHandle();
 
return GL_TRUE;
}
 
_X_HIDDEN __GLXdisplayPrivate *
__glXInitialize(Display * dpy)
{
XExtDisplayInfo *info = __glXFindDisplay(dpy);
XExtData **privList, *private, *found;
__GLXdisplayPrivate *dpyPriv;
XEDataObject dataObj;
int major, minor;
 
if (!XextHasExtension(info))
return NULL;
 
/* See if a display private already exists. If so, return it */
dataObj.display = dpy;
privList = XEHeadOfExtensionList(dataObj);
found = XFindOnExtensionList(privList, info->codes->extension);
if (found)
return (__GLXdisplayPrivate *) found->private_data;
 
/* See if the versions are compatible */
if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
return NULL;
 
/*
** Allocate memory for all the pieces needed for this buffer.
*/
private = malloc(sizeof(XExtData));
if (!private)
return NULL;
dpyPriv = calloc(1, sizeof(__GLXdisplayPrivate));
if (!dpyPriv) {
free(private);
return NULL;
}
 
/*
** Init the display private and then read in the screen config
** structures from the server.
*/
dpyPriv->majorOpcode = info->codes->major_opcode;
dpyPriv->dpy = dpy;
 
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
free(dpyPriv);
free(private);
return NULL;
}
 
/*
** Fill in the private structure. This is the actual structure that
** hangs off of the Display structure. Our private structure is
** referred to by this structure. Got that?
*/
private->number = info->codes->extension;
private->next = 0;
private->free_private = __glXFreeDisplayPrivate;
private->private_data = (char *) dpyPriv;
XAddToExtensionList(privList, private);
 
return dpyPriv;
}
 
#endif /* GLX_DIRECT_RENDERING */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/glxinit.h
0,0 → 1,22
#ifndef GLXINIT_INCLUDED
#define GLXINIT_INCLUDED
 
#include <X11/Xlib.h>
#include <GL/gl.h>
 
typedef struct {
__GLcontextModes *configs;
char *serverGLXexts;
} __GLXscreenConfigs;
 
typedef struct {
Display *dpy;
__GLXscreenConfigs **screenConfigs;
char *serverGLXversion;
int majorOpcode;
struct x11_screen *xscr;
} __GLXdisplayPrivate;
 
extern __GLXdisplayPrivate *__glXInitialize(Display * dpy);
 
#endif /* GLXINIT_INCLUDED */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_dri2.c
0,0 → 1,955
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
 
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
#include "util/u_hash_table.h"
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/drm_driver.h"
#include "egllog.h"
 
#include "native_x11.h"
#include "x11_screen.h"
 
#include "common/native_helper.h"
#ifdef HAVE_WAYLAND_BACKEND
#include "common/native_wayland_drm_bufmgr_helper.h"
#endif
 
#ifdef GLX_DIRECT_RENDERING
 
struct dri2_display {
struct native_display base;
Display *dpy;
boolean own_dpy;
 
const struct native_event_handler *event_handler;
 
struct x11_screen *xscr;
int xscr_number;
const char *dri_driver;
int dri_major, dri_minor;
 
struct dri2_config *configs;
int num_configs;
 
struct util_hash_table *surfaces;
#ifdef HAVE_WAYLAND_BACKEND
struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
#endif
};
 
struct dri2_surface {
struct native_surface base;
Drawable drawable;
enum pipe_format color_format;
struct dri2_display *dri2dpy;
 
unsigned int server_stamp;
unsigned int client_stamp;
int width, height;
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
uint valid_mask;
 
boolean have_back, have_fake;
 
struct x11_drawable_buffer *last_xbufs;
int last_num_xbufs;
};
 
struct dri2_config {
struct native_config base;
};
 
static INLINE struct dri2_display *
dri2_display(const struct native_display *ndpy)
{
return (struct dri2_display *) ndpy;
}
 
static INLINE struct dri2_surface *
dri2_surface(const struct native_surface *nsurf)
{
return (struct dri2_surface *) nsurf;
}
 
static INLINE struct dri2_config *
dri2_config(const struct native_config *nconf)
{
return (struct dri2_config *) nconf;
}
 
/**
* Process the buffers returned by the server.
*/
static void
dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
struct x11_drawable_buffer *xbufs,
int num_xbufs)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
struct pipe_resource templ;
struct winsys_handle whandle;
uint valid_mask;
int i;
 
/* free the old textures */
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
pipe_resource_reference(&dri2surf->textures[i], NULL);
dri2surf->valid_mask = 0x0;
 
dri2surf->have_back = FALSE;
dri2surf->have_fake = FALSE;
 
if (!xbufs)
return;
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
templ.width0 = dri2surf->width;
templ.height0 = dri2surf->height;
templ.depth0 = 1;
templ.array_size = 1;
templ.format = dri2surf->color_format;
templ.bind = PIPE_BIND_RENDER_TARGET;
 
valid_mask = 0x0;
for (i = 0; i < num_xbufs; i++) {
struct x11_drawable_buffer *xbuf = &xbufs[i];
const char *desc;
enum native_attachment natt;
 
switch (xbuf->attachment) {
case DRI2BufferFrontLeft:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
desc = "DRI2 Front Buffer";
break;
case DRI2BufferFakeFrontLeft:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
desc = "DRI2 Fake Front Buffer";
dri2surf->have_fake = TRUE;
break;
case DRI2BufferBackLeft:
natt = NATIVE_ATTACHMENT_BACK_LEFT;
desc = "DRI2 Back Buffer";
dri2surf->have_back = TRUE;
break;
default:
desc = NULL;
break;
}
 
if (!desc || dri2surf->textures[natt]) {
if (!desc)
_eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
else
_eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
continue;
}
 
memset(&whandle, 0, sizeof(whandle));
whandle.stride = xbuf->pitch;
whandle.handle = xbuf->name;
dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}
 
dri2surf->valid_mask = valid_mask;
}
 
/**
* Get the buffers from the server.
*/
static void
dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS * 2];
int num_ins, num_outs, att;
struct x11_drawable_buffer *xbufs;
uint bpp = util_format_get_blocksizebits(dri2surf->color_format);
boolean with_format = FALSE; /* never ask for depth/stencil */
 
/* We must get the front on servers which doesn't support with format
* due to a silly bug in core dri2. You can't copy to/from a buffer
* that you haven't requested and you recive BadValue errors */
if (dri2surf->dri2dpy->dri_minor < 1) {
with_format = FALSE;
buffer_mask |= (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
}
 
/* prepare the attachments */
num_ins = 0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(buffer_mask, att)) {
unsigned int dri2att;
 
switch (att) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
dri2att = DRI2BufferFrontLeft;
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
dri2att = DRI2BufferBackLeft;
break;
case NATIVE_ATTACHMENT_FRONT_RIGHT:
dri2att = DRI2BufferFrontRight;
break;
case NATIVE_ATTACHMENT_BACK_RIGHT:
dri2att = DRI2BufferBackRight;
break;
default:
assert(0);
dri2att = 0;
break;
}
 
dri2atts[num_ins++] = dri2att;
if (with_format)
dri2atts[num_ins++] = bpp;
}
}
if (with_format)
num_ins /= 2;
 
xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
&dri2surf->width, &dri2surf->height,
dri2atts, with_format, num_ins, &num_outs);
 
/* we should be able to do better... */
if (xbufs && dri2surf->last_num_xbufs == num_outs &&
memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) {
FREE(xbufs);
dri2surf->client_stamp = dri2surf->server_stamp;
return;
}
 
dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs);
 
dri2surf->server_stamp++;
dri2surf->client_stamp = dri2surf->server_stamp;
 
FREE(dri2surf->last_xbufs);
dri2surf->last_xbufs = xbufs;
dri2surf->last_num_xbufs = num_outs;
}
 
/**
* Update the buffers of the surface. This is a slow function due to the
* round-trip to the server.
*/
static boolean
dri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
 
dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
 
return ((dri2surf->valid_mask & buffer_mask) == buffer_mask);
}
 
/**
* Return TRUE if the surface receives DRI2_InvalidateBuffers events.
*/
static INLINE boolean
dri2_surface_receive_events(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
return (dri2surf->dri2dpy->dri_minor >= 3);
}
 
static boolean
dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
 
/* copy to real front buffer */
if (dri2surf->have_fake)
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
 
/* force buffers to be updated in next validation call */
if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
&dri2surf->base, dri2surf->server_stamp);
}
 
return TRUE;
}
 
static boolean
dri2_surface_swap_buffers(struct native_surface *nsurf, int num_rects,
const int *rects)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
 
/* copy to front buffer */
if (dri2surf->have_back) {
if (num_rects > 0)
x11_drawable_copy_buffers_region(dri2dpy->xscr, dri2surf->drawable,
num_rects, rects,
DRI2BufferBackLeft, DRI2BufferFrontLeft);
else
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferBackLeft, DRI2BufferFrontLeft);
}
 
/* and update fake front buffer */
if (dri2surf->have_fake) {
if (num_rects > 0)
x11_drawable_copy_buffers_region(dri2dpy->xscr, dri2surf->drawable,
num_rects, rects,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
else
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
}
 
/* force buffers to be updated in next validation call */
if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
&dri2surf->base, dri2surf->server_stamp);
}
 
return TRUE;
}
 
static boolean
dri2_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
boolean ret;
 
if (ctrl->swap_interval)
return FALSE;
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = dri2_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = dri2_surface_swap_buffers(nsurf, ctrl->num_rects, ctrl->rects);
break;
default:
ret = FALSE;
break;
}
 
return ret;
}
 
static boolean
dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
 
if (dri2surf->server_stamp != dri2surf->client_stamp ||
(dri2surf->valid_mask & attachment_mask) != attachment_mask) {
if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask))
return FALSE;
}
 
if (seq_num)
*seq_num = dri2surf->client_stamp;
 
if (textures) {
int att;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(attachment_mask, att)) {
struct pipe_resource *ptex = dri2surf->textures[att];
 
textures[att] = NULL;
pipe_resource_reference(&textures[att], ptex);
}
}
}
 
if (width)
*width = dri2surf->width;
if (height)
*height = dri2surf->height;
 
return TRUE;
}
 
static void
dri2_surface_wait(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
 
if (dri2surf->have_fake) {
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
}
}
 
static void
dri2_surface_destroy(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
int i;
 
FREE(dri2surf->last_xbufs);
 
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
struct pipe_resource *ptex = dri2surf->textures[i];
pipe_resource_reference(&ptex, NULL);
}
 
if (dri2surf->drawable) {
x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
dri2surf->drawable, FALSE);
 
util_hash_table_remove(dri2surf->dri2dpy->surfaces,
(void *) dri2surf->drawable);
}
FREE(dri2surf);
}
 
static struct dri2_surface *
dri2_display_create_surface(struct native_display *ndpy,
Drawable drawable,
enum pipe_format color_format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
struct dri2_surface *dri2surf;
 
dri2surf = CALLOC_STRUCT(dri2_surface);
if (!dri2surf)
return NULL;
 
dri2surf->dri2dpy = dri2dpy;
dri2surf->drawable = drawable;
dri2surf->color_format = color_format;
 
dri2surf->base.destroy = dri2_surface_destroy;
dri2surf->base.present = dri2_surface_present;
dri2surf->base.validate = dri2_surface_validate;
dri2surf->base.wait = dri2_surface_wait;
 
if (drawable) {
x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
/* initialize the geometry */
dri2_surface_update_buffers(&dri2surf->base, 0x0);
 
util_hash_table_set(dri2surf->dri2dpy->surfaces,
(void *) dri2surf->drawable, (void *) &dri2surf->base);
}
 
return dri2surf;
}
 
static struct native_surface *
dri2_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct dri2_surface *dri2surf;
 
dri2surf = dri2_display_create_surface(ndpy,
(Drawable) win, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
 
static struct native_surface *
dri2_display_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf)
{
struct dri2_surface *dri2surf;
 
if (!nconf) {
struct dri2_display *dri2dpy = dri2_display(ndpy);
uint depth, nconf_depth;
int i;
 
depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
for (i = 0; i < dri2dpy->num_configs; i++) {
nconf_depth = util_format_get_blocksizebits(
dri2dpy->configs[i].base.color_format);
/* simple depth match for now */
if (depth == nconf_depth ||
(depth == 24 && depth + 8 == nconf_depth)) {
nconf = &dri2dpy->configs[i].base;
break;
}
}
 
if (!nconf)
return NULL;
}
 
dri2surf = dri2_display_create_surface(ndpy,
(Drawable) pix, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
 
static int
choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
{
int count = 0;
 
switch (mode->rgbBits) {
case 32:
formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case 24:
formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case 16:
formats[count++] = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
break;
}
 
return count;
}
 
static boolean
is_format_supported(struct pipe_screen *screen,
enum pipe_format fmt, unsigned sample_count, boolean is_color)
{
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
(is_color) ? PIPE_BIND_RENDER_TARGET :
PIPE_BIND_DEPTH_STENCIL);
}
 
static boolean
dri2_display_convert_config(struct native_display *ndpy,
const __GLcontextModes *mode,
struct native_config *nconf)
{
enum pipe_format formats[32];
int num_formats, i;
int sample_count = 0;
 
if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
return FALSE;
 
/* only interested in native renderable configs */
if (!mode->xRenderable || !mode->drawableType)
return FALSE;
 
/* fast/slow configs are probably not relevant */
if (mode->visualRating == GLX_SLOW_CONFIG)
return FALSE;
 
nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
if (mode->doubleBufferMode)
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
if (mode->stereoMode) {
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_FRONT_RIGHT;
if (mode->doubleBufferMode)
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_RIGHT;
}
 
/* choose color format */
num_formats = choose_color_format(mode, formats);
for (i = 0; i < num_formats; i++) {
if (is_format_supported(ndpy->screen, formats[i], sample_count, TRUE)) {
nconf->color_format = formats[i];
break;
}
}
if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
 
if ((mode->drawableType & GLX_WINDOW_BIT) && mode->visualID)
nconf->window_bit = TRUE;
if (mode->drawableType & GLX_PIXMAP_BIT)
nconf->pixmap_bit = TRUE;
 
nconf->native_visual_id = mode->visualID;
switch (mode->visualType) {
case GLX_TRUE_COLOR:
nconf->native_visual_type = TrueColor;
break;
case GLX_DIRECT_COLOR:
nconf->native_visual_type = DirectColor;
break;
case GLX_PSEUDO_COLOR:
nconf->native_visual_type = PseudoColor;
break;
case GLX_STATIC_COLOR:
nconf->native_visual_type = StaticColor;
break;
case GLX_GRAY_SCALE:
nconf->native_visual_type = GrayScale;
break;
case GLX_STATIC_GRAY:
nconf->native_visual_type = StaticGray;
break;
}
nconf->level = mode->level;
 
if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
nconf->transparent_rgb = TRUE;
nconf->transparent_rgb_values[0] = mode->transparentRed;
nconf->transparent_rgb_values[1] = mode->transparentGreen;
nconf->transparent_rgb_values[2] = mode->transparentBlue;
}
 
return TRUE;
}
 
static const struct native_config **
dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
const struct native_config **configs;
int i;
 
/* first time */
if (!dri2dpy->configs) {
const __GLcontextModes *modes;
int num_modes, count;
 
modes = x11_screen_get_glx_configs(dri2dpy->xscr);
if (!modes)
return NULL;
num_modes = x11_context_modes_count(modes);
 
dri2dpy->configs = CALLOC(num_modes, sizeof(*dri2dpy->configs));
if (!dri2dpy->configs)
return NULL;
 
count = 0;
for (i = 0; i < num_modes; i++) {
struct native_config *nconf = &dri2dpy->configs[count].base;
 
if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) {
int j;
/* look for duplicates */
for (j = 0; j < count; j++) {
if (memcmp(&dri2dpy->configs[j], nconf, sizeof(*nconf)) == 0)
break;
}
if (j == count)
count++;
}
modes = modes->next;
}
 
dri2dpy->num_configs = count;
}
 
configs = MALLOC(dri2dpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < dri2dpy->num_configs; i++)
configs[i] = (const struct native_config *) &dri2dpy->configs[i];
if (num_configs)
*num_configs = dri2dpy->num_configs;
}
 
return configs;
}
 
static boolean
dri2_display_get_pixmap_format(struct native_display *ndpy,
EGLNativePixmapType pix,
enum pipe_format *format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
boolean ret = EGL_TRUE;
uint depth;
 
depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
switch (depth) {
case 32:
case 24:
*format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 16:
*format = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
*format = PIPE_FORMAT_NONE;
ret = EGL_FALSE;
break;
}
 
return ret;
}
 
static int
dri2_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_USE_NATIVE_BUFFER:
/* DRI2GetBuffers uses the native buffers */
val = TRUE;
break;
case NATIVE_PARAM_PRESERVE_BUFFER:
/* DRI2CopyRegion is used */
val = TRUE;
break;
case NATIVE_PARAM_PRESENT_REGION:
val = TRUE;
break;
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
dri2_display_destroy(struct native_display *ndpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
FREE(dri2dpy->configs);
 
if (dri2dpy->base.screen)
dri2dpy->base.screen->destroy(dri2dpy->base.screen);
 
if (dri2dpy->surfaces)
util_hash_table_destroy(dri2dpy->surfaces);
 
if (dri2dpy->xscr)
x11_screen_destroy(dri2dpy->xscr);
if (dri2dpy->own_dpy)
XCloseDisplay(dri2dpy->dpy);
FREE(dri2dpy);
}
 
static void
dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
void *user_data)
{
struct native_display *ndpy = (struct native_display* ) user_data;
struct dri2_display *dri2dpy = dri2_display(ndpy);
struct native_surface *nsurf;
struct dri2_surface *dri2surf;
 
nsurf = (struct native_surface *)
util_hash_table_get(dri2dpy->surfaces, (void *) drawable);
if (!nsurf)
return;
 
dri2surf = dri2_surface(nsurf);
 
dri2surf->server_stamp++;
dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
&dri2surf->base, dri2surf->server_stamp);
}
 
/**
* Initialize DRI2 and pipe screen.
*/
static boolean
dri2_display_init_screen(struct native_display *ndpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
int fd;
 
if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
_eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
return FALSE;
}
 
dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
&dri2dpy->dri_major, &dri2dpy->dri_minor);
 
fd = x11_screen_enable_dri2(dri2dpy->xscr,
dri2_display_invalidate_buffers, &dri2dpy->base);
if (fd < 0)
return FALSE;
 
dri2dpy->base.screen =
dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
dri2dpy->dri_driver, fd);
if (!dri2dpy->base.screen) {
_eglLog(_EGL_DEBUG, "failed to create DRM screen");
return FALSE;
}
 
return TRUE;
}
 
static unsigned
dri2_display_hash_table_hash(void *key)
{
XID drawable = pointer_to_uintptr(key);
return (unsigned) drawable;
}
 
static int
dri2_display_hash_table_compare(void *key1, void *key2)
{
return ((char *) key1 - (char *) key2);
}
 
#ifdef HAVE_WAYLAND_BACKEND
 
static int
dri2_display_authenticate(void *user_data, uint32_t magic)
{
struct native_display *ndpy = user_data;
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
return x11_screen_authenticate(dri2dpy->xscr, magic);
}
 
static struct wayland_drm_callbacks wl_drm_callbacks = {
dri2_display_authenticate,
egl_g3d_wl_drm_helper_reference_buffer,
egl_g3d_wl_drm_helper_unreference_buffer
};
 
static boolean
dri2_display_bind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
if (dri2dpy->wl_server_drm)
return FALSE;
 
dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy,
x11_screen_get_device_name(dri2dpy->xscr),
&wl_drm_callbacks, ndpy, 0);
 
if (!dri2dpy->wl_server_drm)
return FALSE;
return TRUE;
}
 
static boolean
dri2_display_unbind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
if (!dri2dpy->wl_server_drm)
return FALSE;
 
wayland_drm_uninit(dri2dpy->wl_server_drm);
dri2dpy->wl_server_drm = NULL;
 
return TRUE;
}
 
static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = {
dri2_display_bind_wayland_display,
dri2_display_unbind_wayland_display,
egl_g3d_wl_drm_common_wl_buffer_get_resource,
egl_g3d_wl_drm_common_query_buffer
};
 
#endif /* HAVE_WAYLAND_BACKEND */
 
struct native_display *
x11_create_dri2_display(Display *dpy,
const struct native_event_handler *event_handler)
{
struct dri2_display *dri2dpy;
 
dri2dpy = CALLOC_STRUCT(dri2_display);
if (!dri2dpy)
return NULL;
 
dri2dpy->event_handler = event_handler;
 
dri2dpy->dpy = dpy;
if (!dri2dpy->dpy) {
dri2dpy->dpy = XOpenDisplay(NULL);
if (!dri2dpy->dpy) {
dri2_display_destroy(&dri2dpy->base);
return NULL;
}
dri2dpy->own_dpy = TRUE;
}
 
dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
if (!dri2dpy->xscr) {
dri2_display_destroy(&dri2dpy->base);
return NULL;
}
 
dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
dri2_display_hash_table_compare);
if (!dri2dpy->surfaces) {
dri2_display_destroy(&dri2dpy->base);
return NULL;
}
 
dri2dpy->base.init_screen = dri2_display_init_screen;
dri2dpy->base.destroy = dri2_display_destroy;
dri2dpy->base.get_param = dri2_display_get_param;
dri2dpy->base.get_configs = dri2_display_get_configs;
dri2dpy->base.get_pixmap_format = dri2_display_get_pixmap_format;
dri2dpy->base.copy_to_pixmap = native_display_copy_to_pixmap;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
#ifdef HAVE_WAYLAND_BACKEND
dri2dpy->base.wayland_bufmgr = &dri2_display_wayland_bufmgr;
#endif
 
return &dri2dpy->base;
}
 
#else /* GLX_DIRECT_RENDERING */
 
struct native_display *
x11_create_dri2_display(Display *dpy,
const struct native_event_handler *event_handler)
{
return NULL;
}
 
#endif /* GLX_DIRECT_RENDERING */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_x11.c
0,0 → 1,63
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
 
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_string.h"
#include "egllog.h"
 
#include "native_x11.h"
 
static const struct native_event_handler *x11_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy = NULL;
boolean force_sw;
 
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
 
if (force_sw || use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
ndpy = x11_create_ximage_display((Display *) dpy, x11_event_handler);
}
else {
ndpy = x11_create_dri2_display((Display *) dpy, x11_event_handler);
}
 
return ndpy;
}
 
static const struct native_platform x11_platform = {
"X11", /* name */
native_create_display
};
 
const struct native_platform *
native_get_x11_platform(const struct native_event_handler *event_handler)
{
x11_event_handler = event_handler;
return &x11_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_x11.h
0,0 → 1,39
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
 
#ifndef _NATIVE_X11_H_
#define _NATIVE_X11_H_
 
#include "common/native.h"
#include <X11/Xlib.h>
 
struct native_display *
x11_create_ximage_display(Display *dpy,
const struct native_event_handler *event_handler);
 
struct native_display *
x11_create_dri2_display(Display *dpy,
const struct native_event_handler *event_handler);
 
#endif /* _NATIVE_X11_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_ximage.c
0,0 → 1,586
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
 
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "pipe/p_compiler.h"
#include "util/u_inlines.h"
#include "state_tracker/xlib_sw_winsys.h"
#include "util/u_debug.h"
#include "egllog.h"
 
#include "common/native_helper.h"
#include "native_x11.h"
#include "x11_screen.h"
 
struct ximage_display {
struct native_display base;
Display *dpy;
boolean own_dpy;
 
const struct native_event_handler *event_handler;
 
struct x11_screen *xscr;
int xscr_number;
 
struct ximage_config *configs;
int num_configs;
};
 
struct ximage_surface {
struct native_surface base;
Drawable drawable;
enum pipe_format color_format;
XVisualInfo visual;
struct ximage_display *xdpy;
 
unsigned int server_stamp;
unsigned int client_stamp;
 
struct resource_surface *rsurf;
struct xlib_drawable xdraw;
};
 
struct ximage_config {
struct native_config base;
const XVisualInfo *visual;
};
 
static INLINE struct ximage_display *
ximage_display(const struct native_display *ndpy)
{
return (struct ximage_display *) ndpy;
}
 
static INLINE struct ximage_surface *
ximage_surface(const struct native_surface *nsurf)
{
return (struct ximage_surface *) nsurf;
}
 
static INLINE struct ximage_config *
ximage_config(const struct native_config *nconf)
{
return (struct ximage_config *) nconf;
}
 
/**
* Update the geometry of the surface. This is a slow functions.
*/
static void
ximage_surface_update_geometry(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
Status ok;
Window root;
int x, y;
unsigned int w, h, border, depth;
 
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
if (ok && resource_surface_set_size(xsurf->rsurf, w, h))
xsurf->server_stamp++;
}
 
/**
* Update the buffers of the surface.
*/
static boolean
ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
 
if (xsurf->client_stamp != xsurf->server_stamp) {
ximage_surface_update_geometry(&xsurf->base);
xsurf->client_stamp = xsurf->server_stamp;
}
 
return resource_surface_add_resources(xsurf->rsurf, buffer_mask);
}
 
/**
* Emulate an invalidate event.
*/
static void
ximage_surface_invalidate(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_display *xdpy = xsurf->xdpy;
 
xsurf->server_stamp++;
xdpy->event_handler->invalid_surface(&xdpy->base,
&xsurf->base, xsurf->server_stamp);
}
 
static boolean
ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean ret;
 
ret = resource_surface_present(xsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, (void *) &xsurf->xdraw);
/* force buffers to be updated in next validation call */
ximage_surface_invalidate(&xsurf->base);
 
return ret;
}
 
static boolean
ximage_surface_swap_buffers(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean ret;
 
ret = resource_surface_present(xsurf->rsurf,
NATIVE_ATTACHMENT_BACK_LEFT, (void *) &xsurf->xdraw);
 
resource_surface_swap_buffers(xsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
/* the front/back buffers have been swapped */
ximage_surface_invalidate(&xsurf->base);
 
return ret;
}
 
static boolean
ximage_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
boolean ret;
 
if (ctrl->preserve || ctrl->swap_interval)
return FALSE;
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = ximage_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = ximage_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
break;
}
 
return ret;
}
 
static boolean
ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
uint w, h;
 
if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
return FALSE;
 
if (seq_num)
*seq_num = xsurf->client_stamp;
 
if (textures)
resource_surface_get_resources(xsurf->rsurf, textures, attachment_mask);
 
resource_surface_get_size(xsurf->rsurf, &w, &h);
if (width)
*width = w;
if (height)
*height = h;
 
return TRUE;
}
 
static void
ximage_surface_wait(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
XSync(xsurf->xdpy->dpy, FALSE);
/* TODO XGetImage and update the front texture */
}
 
static void
ximage_surface_destroy(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
 
resource_surface_destroy(xsurf->rsurf);
FREE(xsurf);
}
 
static struct ximage_surface *
ximage_display_create_surface(struct native_display *ndpy,
Drawable drawable,
const struct native_config *nconf)
{
struct ximage_display *xdpy = ximage_display(ndpy);
struct ximage_config *xconf = ximage_config(nconf);
struct ximage_surface *xsurf;
 
xsurf = CALLOC_STRUCT(ximage_surface);
if (!xsurf)
return NULL;
 
xsurf->xdpy = xdpy;
xsurf->color_format = xconf->base.color_format;
xsurf->drawable = drawable;
 
xsurf->rsurf = resource_surface_create(xdpy->base.screen,
xsurf->color_format,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT);
if (!xsurf->rsurf) {
FREE(xsurf);
return NULL;
}
 
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
/* initialize the geometry */
ximage_surface_update_geometry(&xsurf->base);
 
xsurf->xdraw.visual = xsurf->visual.visual;
xsurf->xdraw.depth = xsurf->visual.depth;
xsurf->xdraw.drawable = xsurf->drawable;
 
xsurf->base.destroy = ximage_surface_destroy;
xsurf->base.present = ximage_surface_present;
xsurf->base.validate = ximage_surface_validate;
xsurf->base.wait = ximage_surface_wait;
 
return xsurf;
}
 
static struct native_surface *
ximage_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct ximage_surface *xsurf;
 
xsurf = ximage_display_create_surface(ndpy, (Drawable) win, nconf);
return (xsurf) ? &xsurf->base : NULL;
}
 
static enum pipe_format
get_pixmap_format(struct native_display *ndpy, EGLNativePixmapType pix)
{
struct ximage_display *xdpy = ximage_display(ndpy);
enum pipe_format fmt;
uint depth;
 
depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
 
switch (depth) {
case 32:
fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 24:
fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
case 16:
fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
fmt = PIPE_FORMAT_NONE;
break;
}
 
return fmt;
}
 
static struct native_surface *
ximage_display_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf)
{
struct ximage_surface *xsurf;
 
/* find the config */
if (!nconf) {
struct ximage_display *xdpy = ximage_display(ndpy);
enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
int i;
 
if (fmt != PIPE_FORMAT_NONE) {
for (i = 0; i < xdpy->num_configs; i++) {
if (xdpy->configs[i].base.color_format == fmt) {
nconf = &xdpy->configs[i].base;
break;
}
}
}
 
if (!nconf)
return NULL;
}
 
xsurf = ximage_display_create_surface(ndpy, (Drawable) pix, nconf);
return (xsurf) ? &xsurf->base : NULL;
}
 
static enum pipe_format
choose_format(const XVisualInfo *vinfo)
{
enum pipe_format fmt;
/* TODO elaborate the formats */
switch (vinfo->depth) {
case 32:
fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 24:
fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
case 16:
fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
fmt = PIPE_FORMAT_NONE;
break;
}
 
return fmt;
}
 
static const struct native_config **
ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct ximage_display *xdpy = ximage_display(ndpy);
const struct native_config **configs;
int i;
 
/* first time */
if (!xdpy->configs) {
const XVisualInfo *visuals;
int num_visuals, count;
 
visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
if (!visuals)
return NULL;
 
/*
* Create two configs for each visual.
* One with depth/stencil buffer; one without
*/
xdpy->configs = CALLOC(num_visuals * 2, sizeof(*xdpy->configs));
if (!xdpy->configs)
return NULL;
 
count = 0;
for (i = 0; i < num_visuals; i++) {
struct ximage_config *xconf = &xdpy->configs[count];
 
xconf->visual = &visuals[i];
xconf->base.color_format = choose_format(xconf->visual);
if (xconf->base.color_format == PIPE_FORMAT_NONE)
continue;
 
xconf->base.buffer_mask =
(1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
 
xconf->base.window_bit = TRUE;
xconf->base.pixmap_bit = TRUE;
 
xconf->base.native_visual_id = xconf->visual->visualid;
#if defined(__cplusplus) || defined(c_plusplus)
xconf->base.native_visual_type = xconf->visual->c_class;
#else
xconf->base.native_visual_type = xconf->visual->class;
#endif
 
count++;
}
 
xdpy->num_configs = count;
}
 
configs = MALLOC(xdpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < xdpy->num_configs; i++)
configs[i] = (const struct native_config *) &xdpy->configs[i];
if (num_configs)
*num_configs = xdpy->num_configs;
}
return configs;
}
 
static boolean
ximage_display_get_pixmap_format(struct native_display *ndpy,
EGLNativePixmapType pix,
enum pipe_format *format)
{
struct ximage_display *xdpy = ximage_display(ndpy);
 
*format = get_pixmap_format(&xdpy->base, pix);
 
return (*format != PIPE_FORMAT_NONE);
}
 
static boolean
ximage_display_copy_to_pixmap(struct native_display *ndpy,
EGLNativePixmapType pix,
struct pipe_resource *src)
{
/* fast path to avoid unnecessary allocation and resource_copy_region */
if (src->bind & PIPE_BIND_DISPLAY_TARGET) {
struct ximage_display *xdpy = ximage_display(ndpy);
enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
const struct ximage_config *xconf = NULL;
struct xlib_drawable xdraw;
int i;
 
if (fmt == PIPE_FORMAT_NONE || src->format != fmt)
return FALSE;
 
for (i = 0; i < xdpy->num_configs; i++) {
if (xdpy->configs[i].base.color_format == fmt) {
xconf = &xdpy->configs[i];
break;
}
}
if (!xconf)
return FALSE;
 
memset(&xdraw, 0, sizeof(xdraw));
xdraw.visual = xconf->visual->visual;
xdraw.depth = xconf->visual->depth;
xdraw.drawable = (Drawable) pix;
 
xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
src, 0, 0, &xdraw);
 
return TRUE;
}
 
return native_display_copy_to_pixmap(ndpy, pix, src);
}
 
static int
ximage_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_USE_NATIVE_BUFFER:
/* private buffers are allocated */
val = FALSE;
break;
case NATIVE_PARAM_PRESERVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
ximage_display_destroy(struct native_display *ndpy)
{
struct ximage_display *xdpy = ximage_display(ndpy);
 
FREE(xdpy->configs);
 
ndpy_uninit(ndpy);
 
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
XCloseDisplay(xdpy->dpy);
FREE(xdpy);
}
 
static boolean
ximage_display_init_screen(struct native_display *ndpy)
{
struct ximage_display *xdpy = ximage_display(ndpy);
struct sw_winsys *winsys;
 
winsys = xlib_create_sw_winsys(xdpy->dpy);
if (!winsys)
return FALSE;
 
xdpy->base.screen =
xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
if (!xdpy->base.screen) {
if (winsys->destroy)
winsys->destroy(winsys);
return FALSE;
}
 
return TRUE;
}
 
struct native_display *
x11_create_ximage_display(Display *dpy,
const struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
 
xdpy = CALLOC_STRUCT(ximage_display);
if (!xdpy)
return NULL;
 
xdpy->dpy = dpy;
if (!xdpy->dpy) {
xdpy->dpy = XOpenDisplay(NULL);
if (!xdpy->dpy) {
FREE(xdpy);
return NULL;
}
xdpy->own_dpy = TRUE;
}
 
xdpy->event_handler = event_handler;
 
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
if (!xdpy->xscr) {
if (xdpy->own_dpy)
XCloseDisplay(xdpy->dpy);
FREE(xdpy);
return NULL;
}
 
xdpy->base.init_screen = ximage_display_init_screen;
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_param = ximage_display_get_param;
 
xdpy->base.get_configs = ximage_display_get_configs;
xdpy->base.get_pixmap_format = ximage_display_get_pixmap_format;
xdpy->base.copy_to_pixmap = ximage_display_copy_to_pixmap;
xdpy->base.create_window_surface = ximage_display_create_window_surface;
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
 
return &xdpy->base;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/x11_screen.c
0,0 → 1,488
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
 
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <xf86drm.h>
#include <X11/Xlibint.h>
#include <X11/extensions/XShm.h>
 
#include "util/u_memory.h"
#include "egllog.h"
 
#include "x11_screen.h"
#include "dri2.h"
#include "glxinit.h"
 
struct x11_screen {
Display *dpy;
int number;
 
/*
* This is used to fetch GLX visuals/fbconfigs. It steals code from GLX.
* It might be better to rewrite the part in Xlib or XCB.
*/
__GLXdisplayPrivate *glx_dpy;
 
int dri_major, dri_minor;
char *dri_driver;
char *dri_device;
int dri_fd;
 
x11_drawable_invalidate_buffers dri_invalidate_buffers;
void *dri_user_data;
 
XVisualInfo *visuals;
int num_visuals;
 
/* cached values for x11_drawable_get_depth */
Drawable last_drawable;
unsigned int last_depth;
};
 
 
/**
* Create a X11 screen.
*/
struct x11_screen *
x11_screen_create(Display *dpy, int screen)
{
struct x11_screen *xscr;
 
if (screen >= ScreenCount(dpy))
return NULL;
 
xscr = CALLOC_STRUCT(x11_screen);
if (xscr) {
xscr->dpy = dpy;
xscr->number = screen;
 
xscr->dri_major = -1;
xscr->dri_fd = -1;
}
return xscr;
}
 
/**
* Destroy a X11 screen.
*/
void
x11_screen_destroy(struct x11_screen *xscr)
{
if (xscr->dri_fd >= 0)
close(xscr->dri_fd);
free(xscr->dri_driver);
free(xscr->dri_device);
 
#ifdef GLX_DIRECT_RENDERING
/* xscr->glx_dpy will be destroyed with the X display */
if (xscr->glx_dpy)
xscr->glx_dpy->xscr = NULL;
#endif
 
free(xscr->visuals);
FREE(xscr);
}
 
#ifdef GLX_DIRECT_RENDERING
 
static boolean
x11_screen_init_dri2(struct x11_screen *xscr)
{
if (xscr->dri_major < 0) {
int eventBase, errorBase;
 
if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) ||
!DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor))
xscr->dri_major = -1;
}
return (xscr->dri_major >= 0);
}
 
static boolean
x11_screen_init_glx(struct x11_screen *xscr)
{
if (!xscr->glx_dpy)
xscr->glx_dpy = __glXInitialize(xscr->dpy);
return (xscr->glx_dpy != NULL);
}
 
#endif /* GLX_DIRECT_RENDERING */
 
/**
* Return true if the screen supports the extension.
*/
boolean
x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext)
{
boolean supported = FALSE;
 
switch (ext) {
case X11_SCREEN_EXTENSION_XSHM:
supported = XShmQueryExtension(xscr->dpy);
break;
#ifdef GLX_DIRECT_RENDERING
case X11_SCREEN_EXTENSION_GLX:
supported = x11_screen_init_glx(xscr);
break;
case X11_SCREEN_EXTENSION_DRI2:
supported = x11_screen_init_dri2(xscr);
break;
#endif
default:
break;
}
 
return supported;
}
 
/**
* Return the X visuals.
*/
const XVisualInfo *
x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals)
{
if (!xscr->visuals) {
XVisualInfo vinfo_template;
vinfo_template.screen = xscr->number;
xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask,
&vinfo_template, &xscr->num_visuals);
}
 
if (num_visuals)
*num_visuals = xscr->num_visuals;
return xscr->visuals;
}
 
/**
* Return the depth of a drawable.
*
* Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
*/
uint
x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
{
unsigned int depth;
 
if (drawable != xscr->last_drawable) {
Window root;
int x, y;
unsigned int w, h, border;
Status ok;
 
ok = XGetGeometry(xscr->dpy, drawable, &root,
&x, &y, &w, &h, &border, &depth);
if (!ok)
depth = 0;
 
xscr->last_drawable = drawable;
xscr->last_depth = depth;
}
else {
depth = xscr->last_depth;
}
 
return depth;
}
 
#ifdef GLX_DIRECT_RENDERING
 
/**
* Return the GLX fbconfigs.
*/
const __GLcontextModes *
x11_screen_get_glx_configs(struct x11_screen *xscr)
{
return (x11_screen_init_glx(xscr))
? xscr->glx_dpy->screenConfigs[xscr->number]->configs
: NULL;
}
 
/**
* Probe the screen for the DRI2 driver name.
*/
const char *
x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor)
{
if (!x11_screen_init_dri2(xscr))
return NULL;
 
/* get the driver name and the device name */
if (!xscr->dri_driver) {
if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
&xscr->dri_driver, &xscr->dri_device))
xscr->dri_driver = xscr->dri_device = NULL;
}
if (major)
*major = xscr->dri_major;
if (minor)
*minor = xscr->dri_minor;
 
return xscr->dri_driver;
}
 
/**
* Enable DRI2 and returns the file descriptor of the DRM device. The file
* descriptor will be closed automatically when the screen is destoryed.
*/
int
x11_screen_enable_dri2(struct x11_screen *xscr,
x11_drawable_invalidate_buffers invalidate_buffers,
void *user_data)
{
if (xscr->dri_fd < 0) {
int fd;
drm_magic_t magic;
 
/* get the driver name and the device name first */
if (!x11_screen_probe_dri2(xscr, NULL, NULL))
return -1;
 
#ifdef O_CLOEXEC
fd = open(xscr->dri_device, O_RDWR | O_CLOEXEC);
if (fd == -1 && errno == EINVAL)
#endif
{
fd = open(xscr->dri_device, O_RDWR);
if (fd != -1)
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
if (fd < 0) {
_eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device);
return -1;
}
 
memset(&magic, 0, sizeof(magic));
if (drmGetMagic(fd, &magic)) {
_eglLog(_EGL_WARNING, "failed to get magic");
close(fd);
return -1;
}
 
if (!DRI2Authenticate(xscr->dpy,
RootWindow(xscr->dpy, xscr->number), magic)) {
_eglLog(_EGL_WARNING, "failed to authenticate magic");
close(fd);
return -1;
}
 
if (!x11_screen_init_glx(xscr)) {
_eglLog(_EGL_WARNING, "failed to initialize GLX");
close(fd);
return -1;
}
if (xscr->glx_dpy->xscr) {
_eglLog(_EGL_WARNING,
"display is already managed by another x11 screen");
close(fd);
return -1;
}
 
xscr->glx_dpy->xscr = xscr;
xscr->dri_invalidate_buffers = invalidate_buffers;
xscr->dri_user_data = user_data;
 
xscr->dri_fd = fd;
}
 
return xscr->dri_fd;
}
 
char *
x11_screen_get_device_name(struct x11_screen *xscr)
{
return xscr->dri_device;
}
 
int
x11_screen_authenticate(struct x11_screen *xscr, uint32_t id)
{
boolean authenticated;
 
authenticated = DRI2Authenticate(xscr->dpy,
RootWindow(xscr->dpy, xscr->number), id);
return authenticated ? 0 : -1;
}
 
/**
* Create/Destroy the DRI drawable.
*/
void
x11_drawable_enable_dri2(struct x11_screen *xscr,
Drawable drawable, boolean on)
{
if (on)
DRI2CreateDrawable(xscr->dpy, drawable);
else
DRI2DestroyDrawable(xscr->dpy, drawable);
}
 
/**
* Copy between buffers of the DRI2 drawable.
*/
void
x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
int num_rects, const int *rects,
int src_buf, int dst_buf)
{
XserverRegion region;
XRectangle *rectangles = CALLOC(num_rects, sizeof(XRectangle));
 
for (int i = 0; i < num_rects; i++) {
rectangles[i].x = rects[i * 4 + 0];
rectangles[i].y = rects[i * 4 + 1];
rectangles[i].width = rects[i * 4 + 2];
rectangles[i].height = rects[i * 4 + 3];
}
 
region = XFixesCreateRegion(xscr->dpy, rectangles, num_rects);
DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
XFixesDestroyRegion(xscr->dpy, region);
FREE(rectangles);
}
 
/**
* Get the buffers of the DRI2 drawable. The returned array should be freed.
*/
struct x11_drawable_buffer *
x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
int *width, int *height, unsigned int *attachments,
boolean with_format, int num_ins, int *num_outs)
{
DRI2Buffer *dri2bufs;
 
if (with_format)
dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height,
attachments, num_ins, num_outs);
else
dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height,
attachments, num_ins, num_outs);
 
return (struct x11_drawable_buffer *) dri2bufs;
}
 
/**
* Create a mode list of the given size.
*/
__GLcontextModes *
x11_context_modes_create(unsigned count)
{
const size_t size = sizeof(__GLcontextModes);
__GLcontextModes *base = NULL;
__GLcontextModes **next;
unsigned i;
 
next = &base;
for (i = 0; i < count; i++) {
*next = (__GLcontextModes *) CALLOC(1, size);
if (*next == NULL) {
x11_context_modes_destroy(base);
base = NULL;
break;
}
next = &((*next)->next);
}
 
return base;
}
 
/**
* Destroy a mode list.
*/
void
x11_context_modes_destroy(__GLcontextModes *modes)
{
while (modes != NULL) {
__GLcontextModes *next = modes->next;
FREE(modes);
modes = next;
}
}
 
/**
* Return the number of the modes in the mode list.
*/
unsigned
x11_context_modes_count(const __GLcontextModes *modes)
{
const __GLcontextModes *mode;
int count = 0;
for (mode = modes; mode; mode = mode->next)
count++;
return count;
}
 
extern void
dri2InvalidateBuffers(Display *dpy, XID drawable);
 
/**
* This is called from src/glx/dri2.c.
*/
void
dri2InvalidateBuffers(Display *dpy, XID drawable)
{
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
struct x11_screen *xscr = NULL;
 
if (priv && priv->xscr)
xscr = priv->xscr;
if (!xscr || !xscr->dri_invalidate_buffers)
return;
 
xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data);
}
 
extern unsigned
dri2GetSwapEventType(Display *dpy, XID drawable);
 
extern void *
dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id);
 
extern void *
GetGLXDrawable(Display *dpy, XID drawable);
 
/**
* This is also called from src/glx/dri2.c.
*/
unsigned dri2GetSwapEventType(Display *dpy, XID drawable)
{
return 0;
}
 
void *
dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
{
return NULL;
}
 
void *
GetGLXDrawable(Display *dpy, XID drawable)
{
return NULL;
}
 
#endif /* GLX_DIRECT_RENDERING */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/x11_screen.h
0,0 → 1,133
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
 
#ifndef _X11_SCREEN_H_
#define _X11_SCREEN_H_
 
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/dri2tokens.h>
#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
#include "glcore.h" /* for __GLcontextModes */
#include "pipe/p_compiler.h"
#include "common/native.h"
 
enum x11_screen_extension {
X11_SCREEN_EXTENSION_XSHM,
X11_SCREEN_EXTENSION_GLX,
X11_SCREEN_EXTENSION_DRI2,
};
 
/* the same as DRI2Buffer */
struct x11_drawable_buffer {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
};
 
struct x11_screen;
 
typedef void (*x11_drawable_invalidate_buffers)(struct x11_screen *xscr,
Drawable drawable,
void *user_data);
 
struct x11_screen *
x11_screen_create(Display *dpy, int screen);
 
void
x11_screen_destroy(struct x11_screen *xscr);
 
boolean
x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext);
 
const XVisualInfo *
x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals);
 
uint
x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
 
#ifdef GLX_DIRECT_RENDERING
 
/* GLX */
const __GLcontextModes *
x11_screen_get_glx_configs(struct x11_screen *xscr);
 
const __GLcontextModes *
x11_screen_get_glx_visuals(struct x11_screen *xscr);
 
__GLcontextModes *
x11_context_modes_create(unsigned count);
 
void
x11_context_modes_destroy(__GLcontextModes *modes);
 
unsigned
x11_context_modes_count(const __GLcontextModes *modes);
 
/* DRI2 */
const char *
x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor);
 
int
x11_screen_enable_dri2(struct x11_screen *xscr,
x11_drawable_invalidate_buffers invalidate_buffers,
void *user_data);
 
char *
x11_screen_get_device_name(struct x11_screen *xscr);
 
int
x11_screen_authenticate(struct x11_screen *xscr, uint32_t id);
 
void
x11_drawable_enable_dri2(struct x11_screen *xscr,
Drawable drawable, boolean on);
 
void
x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
int num_rects, const int *rects,
int src_buf, int dst_buf);
 
/**
* Copy between buffers of the DRI2 drawable.
*/
static INLINE void
x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
int x, int y, int width, int height,
int src_buf, int dst_buf)
{
int rect[4] = { x, y, width, height };
x11_drawable_copy_buffers_region(xscr, drawable, 1, rect, src_buf, dst_buf);
}
 
struct x11_drawable_buffer *
x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
int *width, int *height, unsigned int *attachments,
boolean with_format, int num_ins, int *num_outs);
 
#endif /* GLX_DIRECT_RENDERING */
 
#endif /* _X11_SCREEN_H_ */