mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-23 09:30:36 +02:00
vl: rewrite vl DRI backend using XCB
v2: also set array_size of texture Signed-off-by: Christian König <deathsimple@vodafone.de>
This commit is contained in:
parent
6b024464e8
commit
80b40a4841
7 changed files with 148 additions and 859 deletions
|
|
@ -1579,19 +1579,19 @@ if test "x$enable_gallium_g3dvl" = xyes; then
|
|||
fi
|
||||
|
||||
if test "x$enable_xvmc" = xyes; then
|
||||
PKG_CHECK_MODULES([XVMC], [xvmc >= 1.0.6])
|
||||
PKG_CHECK_MODULES([XVMC], [xvmc >= 1.0.6 x11-xcb xcb-dri2 xcb-xfixes])
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xvmc"
|
||||
HAVE_ST_XVMC="yes"
|
||||
fi
|
||||
|
||||
if test "x$enable_vdpau" = xyes; then
|
||||
PKG_CHECK_MODULES([VDPAU], [vdpau >= 0.4.1])
|
||||
PKG_CHECK_MODULES([VDPAU], [vdpau >= 0.4.1 x11-xcb xcb-dri2 xcb-xfixes])
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vdpau"
|
||||
HAVE_ST_VDPAU="yes"
|
||||
fi
|
||||
|
||||
if test "x$enable_va" = xyes; then
|
||||
PKG_CHECK_MODULES([LIBVA], [libva = 0.31.1])
|
||||
PKG_CHECK_MODULES([LIBVA], [libva = 0.31.1 x11-xcb xcb-dri2 xcb-xfixes])
|
||||
AC_MSG_WARN([vaapi state tracker currently unmaintained])
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS va"
|
||||
HAVE_ST_VA="yes"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ INCLUDES = -I$(TOP)/src/gallium/include \
|
|||
-I$(TOP)/src/gallium/winsys/g3dvl \
|
||||
$(DRIVER_INCLUDES)
|
||||
DEFINES = -DGALLIUM_TRACE -DVER_MAJOR=$(VDPAU_MAJOR) -DVER_MINOR=$(VDPAU_MINOR) $(DRIVER_DEFINES)
|
||||
LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lvdpau -lXext -lX11 -lm -lrt
|
||||
LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lvdpau -lX11-xcb -lxcb-dri2 -lxcb-xfixes -lm -lrt
|
||||
STATE_TRACKER_LIB = $(TOP)/src/gallium/state_trackers/vdpau/libvdpautracker.a
|
||||
|
||||
ifeq ($(MESA_LLVM),1)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ INCLUDES = -I$(TOP)/src/gallium/include \
|
|||
-I$(TOP)/src/gallium/winsys/g3dvl \
|
||||
$(DRIVER_INCLUDES)
|
||||
DEFINES = -DGALLIUM_TRACE $(DRIVER_DEFINES)
|
||||
LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lXv -lX11 -lm
|
||||
LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lXv -lX11-xcb -lxcb-dri2 -lxcb-xfixes -lm
|
||||
STATE_TRACKER_LIB = $(TOP)/src/gallium/state_trackers/xvmc/libxvmctracker.a
|
||||
|
||||
ifeq ($(MESA_LLVM),1)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ LIBRARY_INCLUDES = -I$(TOP)/src/gallium/winsys/g3dvl \
|
|||
$(shell $(PKG_CONFIG) libdrm --cflags-only-I)
|
||||
|
||||
C_SOURCES = \
|
||||
dri2.c \
|
||||
dri_winsys.c
|
||||
|
||||
include ../../../Makefile.template
|
||||
|
|
|
|||
|
|
@ -1,666 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Soft-
|
||||
* ware"), to deal in the Software without restriction, including without
|
||||
* limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, provided that the above copyright
|
||||
* notice(s) and this permission notice appear in all copies of the Soft-
|
||||
* ware and that both the above copyright notice(s) and this permission
|
||||
* notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
||||
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
|
||||
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
|
||||
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
|
||||
* QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
|
||||
* MANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall
|
||||
* not be used in advertising or otherwise to promote the sale, use or
|
||||
* other dealings in this Software without prior written authorization of
|
||||
* the copyright holder.
|
||||
*
|
||||
* Authors:
|
||||
* Kristian Høgsberg (krh@redhat.com)
|
||||
*/
|
||||
|
||||
|
||||
#define NEED_REPLIES
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/Xext.h>
|
||||
#include <X11/extensions/extutil.h>
|
||||
#include <X11/extensions/dri2proto.h>
|
||||
#include "xf86drm.h"
|
||||
#include "dri2.h"
|
||||
#if 0
|
||||
#include "glxclient.h"
|
||||
#include "GL/glxext.h"
|
||||
#endif
|
||||
|
||||
/* Allow the build to work with an older versions of dri2proto.h and
|
||||
* dri2tokens.h.
|
||||
*/
|
||||
#if DRI2_MINOR < 1
|
||||
#undef DRI2_MINOR
|
||||
#define DRI2_MINOR 1
|
||||
#define X_DRI2GetBuffersWithFormat 7
|
||||
#endif
|
||||
|
||||
|
||||
static char dri2ExtensionName[] = DRI2_NAME;
|
||||
static XExtensionInfo *dri2Info;
|
||||
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
|
||||
|
||||
static Bool
|
||||
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
|
||||
static Status
|
||||
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
|
||||
|
||||
static /* const */ XExtensionHooks dri2ExtensionHooks = {
|
||||
NULL, /* create_gc */
|
||||
NULL, /* copy_gc */
|
||||
NULL, /* flush_gc */
|
||||
NULL, /* free_gc */
|
||||
NULL, /* create_font */
|
||||
NULL, /* free_font */
|
||||
DRI2CloseDisplay, /* close_display */
|
||||
DRI2WireToEvent, /* wire_to_event */
|
||||
DRI2EventToWire, /* event_to_wire */
|
||||
NULL, /* error */
|
||||
NULL, /* error_string */
|
||||
};
|
||||
|
||||
static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
|
||||
dri2Info,
|
||||
dri2ExtensionName,
|
||||
&dri2ExtensionHooks,
|
||||
0, NULL)
|
||||
|
||||
static Bool
|
||||
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
|
||||
{
|
||||
#if 0
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
XExtDisplayInfo *glx_info = __glXFindDisplay(dpy);
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
|
||||
|
||||
#ifdef X_DRI2SwapBuffers
|
||||
case DRI2_BufferSwapComplete:
|
||||
{
|
||||
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
|
||||
xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
|
||||
aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
|
||||
aevent->type =
|
||||
(glx_info->codes->first_event + GLX_BufferSwapComplete) & 0x75;
|
||||
aevent->send_event = (awire->type & 0x80) != 0;
|
||||
aevent->display = dpy;
|
||||
aevent->drawable = awire->drawable;
|
||||
switch (awire->event_type) {
|
||||
case DRI2_EXCHANGE_COMPLETE:
|
||||
aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL;
|
||||
break;
|
||||
case DRI2_BLIT_COMPLETE:
|
||||
aevent->event_type = GLX_BLIT_COMPLETE_INTEL;
|
||||
break;
|
||||
case DRI2_FLIP_COMPLETE:
|
||||
aevent->event_type = GLX_FLIP_COMPLETE_INTEL;
|
||||
break;
|
||||
default:
|
||||
/* unknown swap completion type */
|
||||
return False;
|
||||
}
|
||||
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
|
||||
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
|
||||
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
#ifdef DRI2_InvalidateBuffers
|
||||
case DRI2_InvalidateBuffers:
|
||||
{
|
||||
xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire;
|
||||
|
||||
dri2InvalidateBuffers(dpy, awire->drawable);
|
||||
return False;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
/* client doesn't support server event */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
|
||||
/* We don't actually support this. It doesn't make sense for clients to
|
||||
* send each other DRI2 events.
|
||||
*/
|
||||
static Status
|
||||
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
switch (event->type) {
|
||||
default:
|
||||
/* client doesn't support server event */
|
||||
break;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Bool
|
||||
DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
|
||||
if (XextHasExtension(info)) {
|
||||
*eventBase = info->codes->first_event;
|
||||
*errorBase = info->codes->first_error;
|
||||
return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
Bool
|
||||
DRI2QueryVersion(Display * dpy, int *major, int *minor)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2QueryVersionReply rep;
|
||||
xDRI2QueryVersionReq *req;
|
||||
int i, nevents;
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2QueryVersion, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2QueryVersion;
|
||||
req->majorVersion = DRI2_MAJOR;
|
||||
req->minorVersion = DRI2_MINOR;
|
||||
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
*major = rep.majorVersion;
|
||||
*minor = rep.minorVersion;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
switch (rep.minorVersion) {
|
||||
case 1:
|
||||
nevents = 0;
|
||||
break;
|
||||
case 2:
|
||||
nevents = 1;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
nevents = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < nevents; i++) {
|
||||
XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent);
|
||||
XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2ConnectReply rep;
|
||||
xDRI2ConnectReq *req;
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2Connect, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2Connect;
|
||||
req->window = window;
|
||||
req->driverType = DRI2DriverDRI;
|
||||
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
|
||||
if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
|
||||
*driverName = Xmalloc(rep.driverNameLength + 1);
|
||||
if (*driverName == NULL) {
|
||||
_XEatData(dpy,
|
||||
((rep.driverNameLength + 3) & ~3) +
|
||||
((rep.deviceNameLength + 3) & ~3));
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
_XReadPad(dpy, *driverName, rep.driverNameLength);
|
||||
(*driverName)[rep.driverNameLength] = '\0';
|
||||
|
||||
*deviceName = Xmalloc(rep.deviceNameLength + 1);
|
||||
if (*deviceName == NULL) {
|
||||
Xfree(*driverName);
|
||||
_XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
_XReadPad(dpy, *deviceName, rep.deviceNameLength);
|
||||
(*deviceName)[rep.deviceNameLength] = '\0';
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
DRI2Authenticate(Display * dpy, XID window, drm_magic_t magic)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2AuthenticateReq *req;
|
||||
xDRI2AuthenticateReply rep;
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2Authenticate, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2Authenticate;
|
||||
req->window = window;
|
||||
req->magic = magic;
|
||||
|
||||
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return rep.authenticated;
|
||||
}
|
||||
|
||||
void
|
||||
DRI2CreateDrawable(Display * dpy, XID drawable)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2CreateDrawableReq *req;
|
||||
|
||||
XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2CreateDrawable, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2CreateDrawable;
|
||||
req->drawable = drawable;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
}
|
||||
|
||||
void
|
||||
DRI2DestroyDrawable(Display * dpy, XID drawable)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2DestroyDrawableReq *req;
|
||||
|
||||
XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
|
||||
|
||||
XSync(dpy, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2DestroyDrawable, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2DestroyDrawable;
|
||||
req->drawable = drawable;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
}
|
||||
|
||||
DRI2Buffer *
|
||||
DRI2GetBuffers(Display * dpy, XID drawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count, int *outCount)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2GetBuffersReply rep;
|
||||
xDRI2GetBuffersReq *req;
|
||||
DRI2Buffer *buffers;
|
||||
xDRI2Buffer repBuffer;
|
||||
CARD32 *p;
|
||||
int i;
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReqExtra(DRI2GetBuffers, count * 4, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2GetBuffers;
|
||||
req->drawable = drawable;
|
||||
req->count = count;
|
||||
p = (CARD32 *) & req[1];
|
||||
for (i = 0; i < count; i++)
|
||||
p[i] = attachments[i];
|
||||
|
||||
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*width = rep.width;
|
||||
*height = rep.height;
|
||||
*outCount = rep.count;
|
||||
|
||||
buffers = Xmalloc(rep.count * sizeof buffers[0]);
|
||||
if (buffers == NULL) {
|
||||
_XEatData(dpy, rep.count * sizeof repBuffer);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rep.count; i++) {
|
||||
_XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
|
||||
buffers[i].attachment = repBuffer.attachment;
|
||||
buffers[i].name = repBuffer.name;
|
||||
buffers[i].pitch = repBuffer.pitch;
|
||||
buffers[i].cpp = repBuffer.cpp;
|
||||
buffers[i].flags = repBuffer.flags;
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
||||
|
||||
DRI2Buffer *
|
||||
DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count, int *outCount)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2GetBuffersReply rep;
|
||||
xDRI2GetBuffersReq *req;
|
||||
DRI2Buffer *buffers;
|
||||
xDRI2Buffer repBuffer;
|
||||
CARD32 *p;
|
||||
int i;
|
||||
|
||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2GetBuffersWithFormat;
|
||||
req->drawable = drawable;
|
||||
req->count = count;
|
||||
p = (CARD32 *) & req[1];
|
||||
for (i = 0; i < (count * 2); i++)
|
||||
p[i] = attachments[i];
|
||||
|
||||
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*width = rep.width;
|
||||
*height = rep.height;
|
||||
*outCount = rep.count;
|
||||
|
||||
buffers = Xmalloc(rep.count * sizeof buffers[0]);
|
||||
if (buffers == NULL) {
|
||||
_XEatData(dpy, rep.count * sizeof repBuffer);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rep.count; i++) {
|
||||
_XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
|
||||
buffers[i].attachment = repBuffer.attachment;
|
||||
buffers[i].name = repBuffer.name;
|
||||
buffers[i].pitch = repBuffer.pitch;
|
||||
buffers[i].cpp = repBuffer.cpp;
|
||||
buffers[i].flags = repBuffer.flags;
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
|
||||
CARD32 dest, CARD32 src)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2CopyRegionReq *req;
|
||||
|
||||
XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2CopyRegion, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2CopyRegion;
|
||||
req->drawable = drawable;
|
||||
req->region = region;
|
||||
req->dest = dest;
|
||||
req->src = src;
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
}
|
||||
|
||||
#ifdef X_DRI2SwapBuffers
|
||||
static void
|
||||
load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
|
||||
CARD64 remainder)
|
||||
{
|
||||
req->target_msc_hi = target >> 32;
|
||||
req->target_msc_lo = target & 0xffffffff;
|
||||
req->divisor_hi = divisor >> 32;
|
||||
req->divisor_lo = divisor & 0xffffffff;
|
||||
req->remainder_hi = remainder >> 32;
|
||||
req->remainder_lo = remainder & 0xffffffff;
|
||||
}
|
||||
|
||||
static CARD64
|
||||
vals_to_card64(CARD32 lo, CARD32 hi)
|
||||
{
|
||||
return (CARD64)hi << 32 | lo;
|
||||
}
|
||||
|
||||
void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
|
||||
CARD64 divisor, CARD64 remainder, CARD64 *count)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2SwapBuffersReq *req;
|
||||
xDRI2SwapBuffersReply rep;
|
||||
|
||||
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2SwapBuffers, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2SwapBuffers;
|
||||
req->drawable = drawable;
|
||||
load_swap_req(req, target_msc, divisor, remainder);
|
||||
|
||||
_XReply(dpy, (xReply *)&rep, 0, xFalse);
|
||||
|
||||
*count = vals_to_card64(rep.swap_lo, rep.swap_hi);
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef X_DRI2GetMSC
|
||||
Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc,
|
||||
CARD64 *sbc)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2GetMSCReq *req;
|
||||
xDRI2MSCReply rep;
|
||||
|
||||
XextCheckExtension (dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2GetMSC, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2GetMSC;
|
||||
req->drawable = drawable;
|
||||
|
||||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
|
||||
*ust = vals_to_card64(rep.ust_lo, rep.ust_hi);
|
||||
*msc = vals_to_card64(rep.msc_lo, rep.msc_hi);
|
||||
*sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi);
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef X_DRI2WaitMSC
|
||||
static void
|
||||
load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor,
|
||||
CARD64 remainder)
|
||||
{
|
||||
req->target_msc_hi = target >> 32;
|
||||
req->target_msc_lo = target & 0xffffffff;
|
||||
req->divisor_hi = divisor >> 32;
|
||||
req->divisor_lo = divisor & 0xffffffff;
|
||||
req->remainder_hi = remainder >> 32;
|
||||
req->remainder_lo = remainder & 0xffffffff;
|
||||
}
|
||||
|
||||
Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
|
||||
CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2WaitMSCReq *req;
|
||||
xDRI2MSCReply rep;
|
||||
|
||||
XextCheckExtension (dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2WaitMSC, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2WaitMSC;
|
||||
req->drawable = drawable;
|
||||
load_msc_req(req, target_msc, divisor, remainder);
|
||||
|
||||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
|
||||
*ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo;
|
||||
*msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo;
|
||||
*sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo;
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef X_DRI2WaitSBC
|
||||
static void
|
||||
load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target)
|
||||
{
|
||||
req->target_sbc_hi = target >> 32;
|
||||
req->target_sbc_lo = target & 0xffffffff;
|
||||
}
|
||||
|
||||
Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
|
||||
CARD64 *msc, CARD64 *sbc)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2WaitSBCReq *req;
|
||||
xDRI2MSCReply rep;
|
||||
|
||||
XextCheckExtension (dpy, info, dri2ExtensionName, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2WaitSBC, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2WaitSBC;
|
||||
req->drawable = drawable;
|
||||
load_sbc_req(req, target_sbc);
|
||||
|
||||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return False;
|
||||
}
|
||||
|
||||
*ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo;
|
||||
*msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo;
|
||||
*sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo;
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef X_DRI2SwapInterval
|
||||
void DRI2SwapInterval(Display *dpy, XID drawable, int interval)
|
||||
{
|
||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||
xDRI2SwapIntervalReq *req;
|
||||
|
||||
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(DRI2SwapInterval, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->dri2ReqType = X_DRI2SwapInterval;
|
||||
req->drawable = drawable;
|
||||
req->interval = interval;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007,2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Soft-
|
||||
* ware"), to deal in the Software without restriction, including without
|
||||
* limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, provided that the above copyright
|
||||
* notice(s) and this permission notice appear in all copies of the Soft-
|
||||
* ware and that both the above copyright notice(s) and this permission
|
||||
* notice appear in supporting documentation.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
|
||||
* ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
|
||||
* RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
|
||||
* THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
|
||||
* QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
|
||||
* MANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of a copyright holder shall
|
||||
* not be used in advertising or otherwise to promote the sale, use or
|
||||
* other dealings in this Software without prior written authorization of
|
||||
* the copyright holder.
|
||||
*
|
||||
* Authors:
|
||||
* Kristian Høgsberg (krh@redhat.com)
|
||||
*/
|
||||
|
||||
#ifndef _DRI2_H_
|
||||
#define _DRI2_H_
|
||||
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/dri2tokens.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int attachment;
|
||||
unsigned int name;
|
||||
unsigned int pitch;
|
||||
unsigned int cpp;
|
||||
unsigned int flags;
|
||||
} DRI2Buffer;
|
||||
|
||||
extern Bool
|
||||
DRI2QueryExtension(Display * display, int *eventBase, int *errorBase);
|
||||
|
||||
extern Bool
|
||||
DRI2QueryVersion(Display * display, int *major, int *minor);
|
||||
|
||||
extern Bool
|
||||
DRI2Connect(Display * display, XID window,
|
||||
char **driverName, char **deviceName);
|
||||
|
||||
extern Bool
|
||||
DRI2Authenticate(Display * display, XID window, drm_magic_t magic);
|
||||
|
||||
extern void
|
||||
DRI2CreateDrawable(Display * display, XID drawable);
|
||||
|
||||
extern void
|
||||
DRI2DestroyDrawable(Display * display, XID handle);
|
||||
|
||||
extern DRI2Buffer*
|
||||
DRI2GetBuffers(Display * dpy, XID drawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count,
|
||||
int *outCount);
|
||||
|
||||
/**
|
||||
* \note
|
||||
* This function is only supported with DRI2 version 1.1 or later.
|
||||
*/
|
||||
extern DRI2Buffer*
|
||||
DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments,
|
||||
int count, int *outCount);
|
||||
|
||||
extern void
|
||||
DRI2CopyRegion(Display * dpy, XID drawable,
|
||||
XserverRegion region,
|
||||
CARD32 dest, CARD32 src);
|
||||
|
||||
extern void
|
||||
DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
|
||||
CARD64 remainder, CARD64 *count);
|
||||
|
||||
extern Bool
|
||||
DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
|
||||
|
||||
extern Bool
|
||||
DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
|
||||
CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
|
||||
|
||||
extern Bool
|
||||
DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
|
||||
CARD64 *msc, CARD64 *sbc);
|
||||
|
||||
extern void
|
||||
DRI2SwapInterval(Display *dpy, XID drawable, int interval);
|
||||
|
||||
#endif
|
||||
|
|
@ -29,8 +29,9 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/dri2tokens.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xcb/xfixes.h>
|
||||
#include <xcb/dri2.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
|
|
@ -44,14 +45,16 @@
|
|||
#include "util/u_inlines.h"
|
||||
|
||||
#include "vl_winsys.h"
|
||||
#include "dri2.h"
|
||||
|
||||
struct vl_dri_screen
|
||||
{
|
||||
struct vl_screen base;
|
||||
Display *display;
|
||||
struct util_hash_table *drawable_table;
|
||||
Drawable last_seen_drawable;
|
||||
xcb_connection_t *conn;
|
||||
xcb_drawable_t drawable;
|
||||
xcb_xfixes_region_t region;
|
||||
|
||||
bool flushed;
|
||||
xcb_dri2_copy_region_cookie_t flush_cookie;
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -60,67 +63,93 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
|
|||
unsigned level, unsigned layer,
|
||||
void *context_private)
|
||||
{
|
||||
struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)context_private;
|
||||
XserverRegion region;
|
||||
struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private;
|
||||
|
||||
assert(screen);
|
||||
assert(resource);
|
||||
assert(context_private);
|
||||
|
||||
region = XFixesCreateRegionFromWindow(vl_dri_scrn->display, vl_dri_scrn->last_seen_drawable, WindowRegionBounding);
|
||||
DRI2CopyRegion(vl_dri_scrn->display, vl_dri_scrn->last_seen_drawable, region,
|
||||
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
|
||||
XFixesDestroyRegion(vl_dri_scrn->display, region);
|
||||
if (scrn->flushed)
|
||||
free(xcb_dri2_copy_region_reply(scrn->conn, scrn->flush_cookie, NULL));
|
||||
else
|
||||
scrn->flushed = true;
|
||||
|
||||
scrn->flush_cookie = xcb_dri2_copy_region_unchecked(scrn->conn, scrn->drawable, scrn->region,
|
||||
XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
|
||||
XCB_DRI2_ATTACHMENT_BUFFER_FAKE_FRONT_LEFT);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_dri2_destroy_drawable(struct vl_dri_screen *scrn)
|
||||
{
|
||||
xcb_void_cookie_t destroy_cookie;
|
||||
if (scrn->drawable) {
|
||||
destroy_cookie = xcb_dri2_destroy_drawable_checked(scrn->conn, scrn->drawable);
|
||||
/* ignore any error here, since the drawable can be destroyed long ago */
|
||||
free(xcb_request_check(scrn->conn, destroy_cookie));
|
||||
}
|
||||
}
|
||||
|
||||
struct pipe_resource*
|
||||
vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
|
||||
{
|
||||
struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
|
||||
unsigned int attachments[1] = {DRI2BufferFrontLeft};
|
||||
static const unsigned int attachments[1] = { XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT };
|
||||
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
|
||||
|
||||
struct winsys_handle dri2_front_handle;
|
||||
struct pipe_resource template, *tex;
|
||||
DRI2Buffer *dri2_front;
|
||||
int w, h, count;
|
||||
|
||||
assert(vl_dri_scrn);
|
||||
xcb_dri2_get_buffers_cookie_t cookie;
|
||||
xcb_dri2_get_buffers_reply_t *reply;
|
||||
xcb_dri2_dri2_buffer_t *buffers;
|
||||
|
||||
if (vl_dri_scrn->last_seen_drawable != drawable) {
|
||||
/* Hash table business depends on this equality */
|
||||
assert(None == NULL);
|
||||
Drawable lookup_drawable = (Drawable)util_hash_table_get(vl_dri_scrn->drawable_table, (void*)drawable);
|
||||
if (lookup_drawable == None) {
|
||||
DRI2CreateDrawable(vl_dri_scrn->display, drawable);
|
||||
util_hash_table_set(vl_dri_scrn->drawable_table, (void*)drawable, (void*)drawable);
|
||||
}
|
||||
vl_dri_scrn->last_seen_drawable = drawable;
|
||||
assert(scrn);
|
||||
|
||||
if (scrn->drawable != drawable) {
|
||||
vl_dri2_destroy_drawable(scrn);
|
||||
xcb_dri2_create_drawable(scrn->conn, drawable);
|
||||
scrn->drawable = drawable;
|
||||
}
|
||||
|
||||
dri2_front = DRI2GetBuffers(vl_dri_scrn->display, drawable, &w, &h, attachments, 1, &count);
|
||||
if (scrn->region)
|
||||
xcb_xfixes_destroy_region(scrn->conn, scrn->region);
|
||||
else
|
||||
scrn->region = xcb_generate_id(scrn->conn);
|
||||
|
||||
assert(count == 1);
|
||||
xcb_xfixes_create_region_from_window(scrn->conn, scrn->region, drawable, XCB_SHAPE_SK_BOUNDING);
|
||||
|
||||
if (!dri2_front)
|
||||
cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, drawable, 1, 1, attachments);
|
||||
reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL);
|
||||
if (!reply)
|
||||
return NULL;
|
||||
|
||||
buffers = xcb_dri2_get_buffers_buffers(reply);
|
||||
if (!buffers) {
|
||||
free(reply);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(reply->count == 1);
|
||||
|
||||
memset(&dri2_front_handle, 0, sizeof(dri2_front_handle));
|
||||
dri2_front_handle.type = DRM_API_HANDLE_TYPE_SHARED;
|
||||
dri2_front_handle.handle = dri2_front->name;
|
||||
dri2_front_handle.stride = dri2_front->pitch;
|
||||
dri2_front_handle.handle = buffers[0].name;
|
||||
dri2_front_handle.stride = buffers[0].pitch;
|
||||
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
|
||||
template.last_level = 0;
|
||||
template.width0 = w;
|
||||
template.height0 = h;
|
||||
template.width0 = reply->width;
|
||||
template.height0 = reply->height;
|
||||
template.depth0 = 1;
|
||||
template.array_size = 1;
|
||||
template.usage = PIPE_USAGE_STATIC;
|
||||
template.bind = PIPE_BIND_RENDER_TARGET;
|
||||
template.flags = 0;
|
||||
|
||||
tex = vl_dri_scrn->base.pscreen->resource_from_handle(vl_dri_scrn->base.pscreen, &template, &dri2_front_handle);
|
||||
Xfree(dri2_front);
|
||||
tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_front_handle);
|
||||
free(reply);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
|
@ -131,44 +160,67 @@ vl_screen_get_private(struct vl_screen *vscreen)
|
|||
return vscreen;
|
||||
}
|
||||
|
||||
static unsigned drawable_hash(void *key)
|
||||
{
|
||||
Drawable drawable = (Drawable)key;
|
||||
assert(drawable != None);
|
||||
return util_hash_crc32(&drawable, sizeof(Drawable));
|
||||
}
|
||||
|
||||
static int drawable_cmp(void *key1, void *key2)
|
||||
{
|
||||
Drawable d1 = (Drawable)key1;
|
||||
Drawable d2 = (Drawable)key2;
|
||||
assert(d1 != None);
|
||||
assert(d2 != None);
|
||||
return d1 != d2;
|
||||
}
|
||||
|
||||
struct vl_screen*
|
||||
vl_screen_create(Display *display, int screen)
|
||||
{
|
||||
struct vl_dri_screen *vl_dri_scrn;
|
||||
drm_magic_t magic;
|
||||
char *drvName;
|
||||
char *devName;
|
||||
struct vl_dri_screen *scrn;
|
||||
const xcb_query_extension_reply_t *extension;
|
||||
xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
|
||||
xcb_xfixes_query_version_reply_t *xfixes_query = NULL;
|
||||
xcb_dri2_query_version_cookie_t dri2_query_cookie;
|
||||
xcb_dri2_query_version_reply_t *dri2_query = NULL;
|
||||
xcb_dri2_connect_cookie_t connect_cookie;
|
||||
xcb_dri2_connect_reply_t *connect = NULL;
|
||||
xcb_dri2_authenticate_cookie_t authenticate_cookie;
|
||||
xcb_dri2_authenticate_reply_t *authenticate = NULL;
|
||||
xcb_screen_iterator_t s;
|
||||
xcb_generic_error_t *error = NULL;
|
||||
char *device_name;
|
||||
int fd;
|
||||
|
||||
drm_magic_t magic;
|
||||
|
||||
assert(display);
|
||||
|
||||
vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen);
|
||||
if (!vl_dri_scrn)
|
||||
goto no_struct;
|
||||
scrn = CALLOC_STRUCT(vl_dri_screen);
|
||||
if (!scrn)
|
||||
return NULL;
|
||||
|
||||
vl_dri_scrn->display = display;
|
||||
if (!DRI2Connect(display, XRootWindow(display, screen), &drvName, &devName))
|
||||
scrn->conn = XGetXCBConnection(display);
|
||||
if (!scrn->conn)
|
||||
goto free_screen;
|
||||
|
||||
fd = open(devName, O_RDWR);
|
||||
Xfree(drvName);
|
||||
Xfree(devName);
|
||||
xcb_prefetch_extension_data(scrn->conn, &xcb_xfixes_id);
|
||||
xcb_prefetch_extension_data(scrn->conn, &xcb_dri2_id);
|
||||
|
||||
extension = xcb_get_extension_data(scrn->conn, &xcb_xfixes_id);
|
||||
if (!(extension && extension->present))
|
||||
goto free_screen;
|
||||
|
||||
extension = xcb_get_extension_data(scrn->conn, &xcb_dri2_id);
|
||||
if (!(extension && extension->present))
|
||||
goto free_screen;
|
||||
|
||||
xfixes_query_cookie = xcb_xfixes_query_version(scrn->conn, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION);
|
||||
xfixes_query = xcb_xfixes_query_version_reply (scrn->conn, xfixes_query_cookie, &error);
|
||||
if (xfixes_query == NULL || error != NULL || xfixes_query->major_version < 2)
|
||||
goto free_screen;
|
||||
|
||||
dri2_query_cookie = xcb_dri2_query_version (scrn->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION);
|
||||
dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error);
|
||||
if (dri2_query == NULL || error != NULL)
|
||||
goto free_screen;
|
||||
|
||||
s = xcb_setup_roots_iterator(xcb_get_setup(scrn->conn));
|
||||
connect_cookie = xcb_dri2_connect_unchecked(scrn->conn, s.data->root, XCB_DRI2_DRIVER_TYPE_DRI);
|
||||
connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL);
|
||||
if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0)
|
||||
goto free_screen;
|
||||
|
||||
device_name = xcb_dri2_connect_device_name(connect);
|
||||
device_name = strndup(device_name, xcb_dri2_connect_device_name_length(connect));
|
||||
fd = open(device_name, O_RDWR);
|
||||
free(device_name);
|
||||
|
||||
if (fd < 0)
|
||||
goto free_screen;
|
||||
|
|
@ -176,38 +228,48 @@ vl_screen_create(Display *display, int screen)
|
|||
if (drmGetMagic(fd, &magic))
|
||||
goto free_screen;
|
||||
|
||||
if (!DRI2Authenticate(display, RootWindow(display, screen), magic))
|
||||
authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn, s.data->root, magic);
|
||||
authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL);
|
||||
|
||||
if (authenticate == NULL || !authenticate->authenticated)
|
||||
goto free_screen;
|
||||
|
||||
vl_dri_scrn->base.pscreen = driver_descriptor.create_screen(fd);
|
||||
|
||||
if (!vl_dri_scrn->base.pscreen)
|
||||
scrn->base.pscreen = driver_descriptor.create_screen(fd);
|
||||
if (!scrn->base.pscreen)
|
||||
goto free_screen;
|
||||
|
||||
vl_dri_scrn->drawable_table = util_hash_table_create(&drawable_hash, &drawable_cmp);
|
||||
if (!vl_dri_scrn->drawable_table)
|
||||
goto no_hash;
|
||||
scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
|
||||
|
||||
vl_dri_scrn->last_seen_drawable = None;
|
||||
vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
|
||||
free(xfixes_query);
|
||||
free(dri2_query);
|
||||
free(connect);
|
||||
free(authenticate);
|
||||
|
||||
return &vl_dri_scrn->base;
|
||||
return &scrn->base;
|
||||
|
||||
no_hash:
|
||||
vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
|
||||
free_screen:
|
||||
FREE(vl_dri_scrn);
|
||||
no_struct:
|
||||
FREE(scrn);
|
||||
|
||||
free(xfixes_query);
|
||||
free(dri2_query);
|
||||
free(connect);
|
||||
free(authenticate);
|
||||
free(error);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vl_screen_destroy(struct vl_screen *vscreen)
|
||||
{
|
||||
struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
|
||||
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
|
||||
|
||||
assert(vscreen);
|
||||
|
||||
util_hash_table_destroy(vl_dri_scrn->drawable_table);
|
||||
vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
|
||||
FREE(vl_dri_scrn);
|
||||
if (scrn->flushed)
|
||||
free(xcb_dri2_copy_region_reply(scrn->conn, scrn->flush_cookie, NULL));
|
||||
if (scrn->region)
|
||||
xcb_xfixes_destroy_region(scrn->conn, scrn->region);
|
||||
vl_dri2_destroy_drawable(scrn);
|
||||
scrn->base.pscreen->destroy(scrn->base.pscreen);
|
||||
FREE(scrn);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue