diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-08-04 13:10:55 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-11-04 15:13:01 +0100 |
commit | 3f46f94324b73ce91f4e555d6c3568f8ef483fb6 (patch) | |
tree | 253933d2f0adb8989c037a2b15bd6797171f7fb8 | |
parent | 430a114355c0ae23bd2c4a29221ff4f31ed99e5b (diff) |
XvMC: Implement Buffer Status retrieval.
-rw-r--r-- | lib/xvmc/xvmc_unichrome.c | 66 | ||||
-rw-r--r-- | lib/xvmc/xvmce.c | 33 | ||||
-rw-r--r-- | lib/xvmc/xvmce.h | 2 | ||||
-rw-r--r-- | lib/xvmc/xvmce_proto.h | 33 | ||||
-rw-r--r-- | src/via_xvmc.c | 112 |
5 files changed, 212 insertions, 34 deletions
diff --git a/lib/xvmc/xvmc_unichrome.c b/lib/xvmc/xvmc_unichrome.c index 6d7c827..e2932b8 100644 --- a/lib/xvmc/xvmc_unichrome.c +++ b/lib/xvmc/xvmc_unichrome.c @@ -65,6 +65,9 @@ static int XvMCE_ErrorBase; static XID current_surface_id = 0; static int current_surface_size = 0; +/* because of the rather abhorrent nature of the XvMC interface. */ +static XvPortID XvMCPortID = 0; + /* * */ @@ -116,6 +119,9 @@ XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, if (status != Success) printf("%s: _xvmc_create_context failed: %d\n", __func__, status); + /* Ok, this seems to be valid, and we can set up the PortID as well */ + XvMCPortID = port; + return status; } @@ -131,6 +137,8 @@ XvMCDestroyContext(Display *display, XvMCContext *context) if (!display || !context) return BadValue; + XvMCPortID = 0; + return _xvmc_destroy_context(display, context); } @@ -211,9 +219,11 @@ XvMCHideSurface(Display *display, XvMCSurface *surface) * */ _X_EXPORT Status -XvMCSyncSurface(Display *display, XvMCSurface *surface) +XvMCFlushSurface(Display *display, XvMCSurface *surface) { - printf("%s: 0x%08X\n", __func__, surface->surface_id); + printf("%s: 0x%08X (%dbytes)\n", __func__, surface->surface_id, current_surface_size); + + /* We don't need to do this with our hardware. */ return Success; } @@ -223,9 +233,32 @@ XvMCSyncSurface(Display *display, XvMCSurface *surface) * */ _X_EXPORT Status -XvMCFlushSurface(Display *display, XvMCSurface *surface) +XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) { - printf("%s: 0x%08X (%dbytes)\n", __func__, surface->surface_id, current_surface_size); + Status status; + int StatusFlags; + + printf("%s: 0x%08X\n", __func__, surface->surface_id); + + status = XVMCEBufferStatus(display, XvMCPortID, + surface->surface_id, &StatusFlags); + if (status != Success) { + fprintf(stderr, "%s: XvMCEBufferStatusGet failed: %d\n", + __func__, status); + return status; + } + + /* since we are slightly smarter than the state that XvMC tracks... */ + *stat = 0; + if (StatusFlags) { + if (StatusFlags & XVMCE_BUFFERSTATUS_DECODING) + /* Just like surface, rendering is for 3d. */ + *stat |= XVMC_RENDERING; + /* ignore XVMCE_BUFFERSTATUS_REFERENCED */ + if (StatusFlags & XVMCE_BUFFERSTATUS_DISPLAYING) + *stat |= XVMC_DISPLAYING; + } else + *stat = 0; return Success; } @@ -235,11 +268,29 @@ XvMCFlushSurface(Display *display, XvMCSurface *surface) * */ _X_EXPORT Status -XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) +XvMCSyncSurface(Display *display, XvMCSurface *surface) { - printf("%s\n", __func__); + Status status; + int StatusFlags, i; - return BadImplementation; + printf("%s: 0x%08X\n", __func__, surface->surface_id); + + for (i = 0; i < 0x1000; i++) { + status = XVMCEBufferStatus(display, XvMCPortID, + surface->surface_id, &StatusFlags); + if (status != Success) { + fprintf(stderr, "%s: XvMCEBufferStatusGet failed: %d\n", + __func__, status); + return status; + } + + if (!StatusFlags) + return Success; + } + + fprintf(stderr, "%s: time out when syncing Buffer 0x%X.\n", + __func__, surface->surface_id); + return BadValue; /* whatever */ } @@ -296,6 +347,7 @@ XvMCPutSlice2(Display *display, XvMCContext *context, return Success; } + /* * */ diff --git a/lib/xvmc/xvmce.c b/lib/xvmc/xvmce.c index 69827d1..88b8473 100644 --- a/lib/xvmc/xvmce.c +++ b/lib/xvmc/xvmce.c @@ -160,3 +160,36 @@ XvMCEQMatrixSend(Display *dpy, XvPortID port, char type, return Success; } +/* + * + */ +Status +XVMCEBufferStatus(Display *dpy, XvPortID port, XID Buffer, int *StatusFlags) +{ + XExtDisplayInfo *info = XvMCEFindDisplay(dpy); + xvmceBufferStatusReq *req; + xvmceBufferStatusReply reply; + Status status; + + XvMCECheckExtension(dpy, info, BadImplementation); + + LockDisplay(dpy); + + XvMCEGetReq(BufferStatus, req); + + req->Port = port; + req->Buffer = Buffer; + + if (_XReply(dpy, (xReply *)&reply, 0, xFalse)) { + *StatusFlags = reply.StatusFlags; + status = Success; + } else { + fprintf(stderr, "%s; Xreply failed.\n", __func__); + status = BadAccess; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return status; +} diff --git a/lib/xvmc/xvmce.h b/lib/xvmc/xvmce.h index 49038c2..de59de2 100644 --- a/lib/xvmc/xvmce.h +++ b/lib/xvmc/xvmce.h @@ -28,5 +28,7 @@ Status XvMCEQueryExtension(Display *display, int *Version, int *Release, int *event_basep, int *error_basep); Status XvMCEQMatrixSend(Display *display, XvPortID port, char type, const unsigned char qmatrix[64]); +Status XVMCEBufferStatus(Display *dpy, XvPortID port, XID Buffer, + int *StatusFlags); #endif /* XVMCE_H */ diff --git a/lib/xvmc/xvmce_proto.h b/lib/xvmc/xvmce_proto.h index bd4706b..3a3989c 100644 --- a/lib/xvmc/xvmce_proto.h +++ b/lib/xvmc/xvmce_proto.h @@ -34,6 +34,7 @@ #define xvmce_QueryExtension 0 #define xvmce_QMatrixSend 1 +#define xvmce_BufferStatus 2 /* * Version, are we compatible? @@ -57,7 +58,7 @@ typedef struct { CARD32 pad4 B32; CARD32 pad5 B32; } xvmceQueryExtensionReply; -#define sz_xvmceQueryExtensionReply 32 +#define sz_xvmceQueryExtensionReply 32 /* * QMatrixSend, upload a Quantization matrix to the MPEG engine. @@ -75,4 +76,34 @@ typedef struct { } xvmceQMatrixSendReq; #define sz_xvmceQMatrixSendReq 12 + +/* + * + */ +typedef struct { + CARD8 reqType; + CARD8 xvmceReqType; /* xvmce_BufferStatus */ + CARD16 length B16; + CARD32 Port B32; + CARD32 Buffer B32; +} xvmceBufferStatusReq; +#define sz_xvmceBufferStatusReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; +#define XVMCE_BUFFERSTATUS_DECODING 1 +#define XVMCE_BUFFERSTATUS_REFERENCED 2 +#define XVMCE_BUFFERSTATUS_DISPLAYING 4 + CARD32 StatusFlags B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xvmceBufferStatusReply; +#define sz_xvmceBufferStatusReply 32 + #endif /* XVMCE_PROTO_H */ diff --git a/src/via_xvmc.c b/src/via_xvmc.c index 1abe972..ebd1103 100644 --- a/src/via_xvmc.c +++ b/src/via_xvmc.c @@ -34,6 +34,15 @@ #include "via_driver.h" #include "via_video.h" +/* Just some placeholders to be able to flesh out the library */ +static XID ViaMCContextID = 0; +static int ViaMCContextWidth = 0; +static int ViaMCContextHeight = 0; + +#define VIAMC_BUFFER_COUNT 8 +static XID ViaMCBufferIDs[VIAMC_BUFFER_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0}; +static int ViaMCBufferStatus[VIAMC_BUFFER_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0}; + /* * * First, our own X protocol to make XvMC less brainless. @@ -60,8 +69,10 @@ XvMCEProcQueryExtension(ClientPtr client) REQUEST_SIZE_MATCH(xvmceQueryExtensionReq); XvMCE_Ext = CheckExtension(XVMCE_EXT_NAME); - if(!XvMCE_Ext || !XvMCE_Ext->extPrivate) + if(!XvMCE_Ext || !XvMCE_Ext->extPrivate) { + xf86Msg(X_WARNING, "%s: Extension not initialised.\n", __func__); return BadMatch; + } rep.type = X_Reply; rep.sequenceNumber = client->sequence; @@ -114,6 +125,61 @@ XvMCEProcQMatrixSend(ClientPtr client) ViaDebug(pScrn->scrnIndex, "%s: type %1X\n", __func__, stuff->Type); + /* !!!! upload to hw here. !!!! */ + + return (client->noClientException); +} + +/* + * + */ +static int +XvMCEProcBufferStatus(ClientPtr client) +{ + ExtensionEntry *XvMCE_Ext; + struct XvMCEPrivates *Private; + ScrnInfoPtr pScrn; + XvPortPtr Port; + int i; + xvmceBufferStatusReply reply; + + REQUEST(xvmceBufferStatusReq); + REQUEST_SIZE_MATCH(xvmceBufferStatusReq); + + XvMCE_Ext = CheckExtension(XVMCE_EXT_NAME); + if (!XvMCE_Ext || !XvMCE_Ext->extPrivate) { + xf86Msg(X_WARNING, "%s: Extension not initialised.\n", __func__); + return BadMatch; + } + + Private = XvMCE_Ext->extPrivate; + pScrn = xf86Screens[Private->scrnIndex]; + + /* Does our client own this port? */ + Port = LookupIDByType(stuff->Port, XvGetRTPort()); + if (!Port) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%s: Client doesn't own this Xv Port.\n", __func__); + return BadAccess; + } + + for (i = 0; i < VIAMC_BUFFER_COUNT; i++) + if (ViaMCBufferIDs[i] == stuff->Buffer) + break; + + if (i == VIAMC_BUFFER_COUNT) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Buffer 0x%08X does not " + "exist.\n", __func__, (unsigned int) stuff->Buffer); + return BadAccess; + } + + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + reply.length = (sizeof(xvmceBufferStatusReply) - sizeof(xGenericReply)) >> 2; + reply.StatusFlags = ViaMCBufferStatus[i]; + + WriteToClient(client, sizeof(xvmceBufferStatusReply), (char *)&reply); + return (client->noClientException); } @@ -130,6 +196,8 @@ XvMCEHandler(ClientPtr client) return XvMCEProcQueryExtension(client); case xvmce_QMatrixSend: return XvMCEProcQMatrixSend(client); + case xvmce_BufferStatus: + return XvMCEProcBufferStatus(client); default: break; } @@ -211,14 +279,6 @@ static XF86MCSurfaceInfoRec ViaMCMpeg2Surface = { static XF86MCSurfaceInfoPtr ViaMCSurfaces[1] = {&ViaMCMpeg2Surface}; -/* Just some placeholders to be able to flesh out the library */ -static XID ViaMCContextID = 0; -static int ViaMCContextWidth = 0; -static int ViaMCContextHeight = 0; - -#define VIAMC_SURFACE_COUNT 8 -static XID ViaMCSurfacesIDs[VIAMC_SURFACE_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0}; - /* * */ @@ -260,26 +320,26 @@ ViaMCDestroyContext(ScrnInfoPtr pScrn, XvMCContextPtr context) * */ static int -ViaMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, - int *num_priv, CARD32 **priv) +ViaMCBufferCreate(ScrnInfoPtr pScrn, XvMCSurfacePtr Buffer, + int *num_priv, CARD32 **priv) { int i; VIAFUNC(pScrn); - if (ViaMCContextID != surface->context->context_id) + if (ViaMCContextID != Buffer->context->context_id) return BadAccess; - for (i = 0; i < VIAMC_SURFACE_COUNT; i++) - if (!ViaMCSurfacesIDs[i]) + for (i = 0; i < VIAMC_BUFFER_COUNT; i++) + if (!ViaMCBufferIDs[i]) break; - if (i == VIAMC_SURFACE_COUNT) + if (i == VIAMC_BUFFER_COUNT) return BadAlloc; ViaDebug(pScrn->scrnIndex, "%s: claimed %d (%08X)\n", - __func__, i, surface->surface_id); - ViaMCSurfacesIDs[i] = surface->surface_id; + __func__, i, Buffer->surface_id); + ViaMCBufferIDs[i] = Buffer->surface_id; return Success; } @@ -288,25 +348,25 @@ ViaMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, * */ static void -ViaMCDestroySurface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface) +ViaMCBufferDestroy(ScrnInfoPtr pScrn, XvMCSurfacePtr Buffer) { int i; VIAFUNC(pScrn); - if (ViaMCContextID != surface->context->context_id) + if (ViaMCContextID != Buffer->context->context_id) return; - for (i = 0; i < VIAMC_SURFACE_COUNT; i++) - if (ViaMCSurfacesIDs[i] == surface->surface_id) + for (i = 0; i < VIAMC_BUFFER_COUNT; i++) + if (ViaMCBufferIDs[i] == Buffer->surface_id) break; - if (i == VIAMC_SURFACE_COUNT) + if (i == VIAMC_BUFFER_COUNT) return; ViaDebug(pScrn->scrnIndex, "%s: released %d (%08X)\n", - __func__, i, surface->surface_id); - ViaMCSurfacesIDs[i] = 0; + __func__, i, Buffer->surface_id); + ViaMCBufferIDs[i] = 0; } /* @@ -336,8 +396,8 @@ static XF86MCAdaptorRec ViaMCAdaptor = { 2, ViaMCSubPictures, ViaMCCreateContext, ViaMCDestroyContext, - ViaMCCreateSurface, - ViaMCDestroySurface, + ViaMCBufferCreate, + ViaMCBufferDestroy, ViaMCCreateSubpicture, ViaMCDestroySubpicture }; |