summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-08-04 13:10:55 +0200
committerLuc Verhaegen <libv@skynet.be>2009-11-04 15:13:01 +0100
commit3f46f94324b73ce91f4e555d6c3568f8ef483fb6 (patch)
tree253933d2f0adb8989c037a2b15bd6797171f7fb8
parent430a114355c0ae23bd2c4a29221ff4f31ed99e5b (diff)
XvMC: Implement Buffer Status retrieval.
-rw-r--r--lib/xvmc/xvmc_unichrome.c66
-rw-r--r--lib/xvmc/xvmce.c33
-rw-r--r--lib/xvmc/xvmce.h2
-rw-r--r--lib/xvmc/xvmce_proto.h33
-rw-r--r--src/via_xvmc.c112
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
};