/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_ */ |