[PATCH libdri2] dri2video support

walter harms wharms at bfs.de
Wed Nov 16 05:36:45 PST 2011



Am 15.11.2011 23:49, schrieb Rob Clark:
> ---
>  Makefile.am                   |   16 ++-
>  include/X11/extensions/dri2.h |   52 +++++++-
>  src/Makefile.am               |    2 +-
>  src/dri2.c                    |  324 ++++++++++++++++++++++++++++++++---------
>  test/Makefile.am              |    6 +-
>  test/dri2-nouveau.c           |    2 +-
>  test/dri2-omap.c              |    2 +-
>  test/dri2test.c               |    4 +-
>  test/dri2videotest.c          |  264 +++++++++++++++++++++++++++++++++
>  9 files changed, 593 insertions(+), 79 deletions(-)
>  create mode 100644 test/dri2videotest.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index 4a7b6a1..d4ce946 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -43,8 +43,16 @@ endif
>  
>  if ENABLE_TEST
>  SUBDIRS            += test
> -bin_PROGRAMS        = dri2test
> -dri2test_SOURCES    = 
> -dri2test_LDFLAGS    = -no-undefined
> -dri2test_LDADD      = test/libdri2test.la src/libdri2.la @DRI2_LIBS@
> +bin_PROGRAMS        = dri2test dri2videotest
> +
> +COMMON_LDFLAGS      = -no-undefined
> +COMMON_LDADD        = src/libdri2.la @DRI2_LIBS@
> +
> +dri2test_SOURCES    =
> +dri2test_LDFLAGS    = $(COMMON_LDFLAGS)
> +dri2test_LDADD      = test/libdri2test.la $(COMMON_LDADD)
> +
> +dri2videotest_SOURCES =
> +dri2videotest_LDFLAGS = $(COMMON_LDFLAGS)
> +dri2videotest_LDADD   = test/libdri2videotest.la $(COMMON_LDADD)
>  endif
> diff --git a/include/X11/extensions/dri2.h b/include/X11/extensions/dri2.h
> index e42cdb6..b15620c 100644
> --- a/include/X11/extensions/dri2.h
> +++ b/include/X11/extensions/dri2.h
> @@ -38,13 +38,14 @@
>  #include <X11/extensions/Xfixes.h>
>  #include <X11/extensions/extutil.h>
>  #include <X11/extensions/dri2tokens.h>
> +#include <X11/Xregion.h>
>  #include <drm.h>
>  
>  typedef struct
>  {
>     unsigned int attachment;
> -   unsigned int name;
> -   unsigned int pitch;
> +   unsigned int names[3];    /* unused entries set to zero.. non-planar formats only use names[0] */
> +   unsigned int pitch[3];    /* unused entries set to zero.. non-planar formats only use pitch[0] */
>     unsigned int cpp;
>     unsigned int flags;
>  } DRI2Buffer;
> @@ -95,6 +96,16 @@ DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
>                           unsigned int *attachments,
>                           int count, int *outCount);
>  
> +/**
> + * \note
> + * This function is only supported with DRI2 version 1.4 or later.
> + * The 'attachments' array is same as with DRI2GetBuffersWithFormat()
> + */
> +DRI2Buffer *
> +DRI2GetBuffersVid(Display * dpy, XID drawable,
> +               int width, int height,
> +               unsigned int *attachments, int count, int *outCount);
> +
>  extern void
>  DRI2CopyRegion(Display * dpy, XID drawable,
>                 XserverRegion region,
> @@ -104,6 +115,15 @@ extern void
>  DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
>  		CARD64 remainder, CARD64 *count);
>  
> +/**
> + * \note
> + * This function is only supported with DRI2 version 1.4 or later.
> + */
> +extern void
> +DRI2SwapBuffersVid(Display *dpy, XID drawable, CARD64 target_msc,
> +		CARD64 divisor, CARD64 remainder, CARD64 *count,
> +		unsigned int source, BoxPtr b);
> +
>  extern Bool
>  DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
>  
> @@ -118,4 +138,32 @@ DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
>  extern void
>  DRI2SwapInterval(Display *dpy, XID drawable, int interval);
>  
> +/**
> + * \note
> + * This function is only supported with DRI2 version 1.4 or later.
> + * length in multiple of CARD32's
> + */
> +extern void
> +DRI2SetAttribute(Display * dpy, XID drawable, Atom attribute,
> +		int len, const CARD32 *val);
> +
> +/**
> + * \note
> + * This function is only supported with DRI2 version 1.4 or later.
> + * The returned attribute should be free'd by caller.. length in
> + * multiple of CARD32's
> + */
> +extern Bool
> +DRI2GetAttribute(Display * dpy, XID drawable, Atom attribute,
> +		int *len, CARD32 **val);
> +
> +/**
> + * \note
> + * This function is only supported with DRI2 version 1.4 or later.
> + * returned formats should be freed by caller
> + */
> +extern Bool
> +DRI2GetFormats(Display * dpy, XID drawable, unsigned int *pnformats,
> +		unsigned int **pformats);
> +
>  #endif
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 07f2492..ac3494a 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -4,7 +4,7 @@ libdri2_la_SOURCES = \
>           dri2.c
>  
>  libdri2_la_LIBADD = @DRI2_LIBS@
> -AM_CFLAGS = $(CWARNFLAGS) @DRI2_CFLAGS@ -I$(top_srcdir)/include @MALLOC_ZERO_CFLAGS@
> +AM_CFLAGS =-I$(top_srcdir)/include $(CWARNFLAGS) @DRI2_CFLAGS@ @MALLOC_ZERO_CFLAGS@
>  
>  libdri2_la_LDFLAGS = -version-number 1:0:0 -no-undefined
>  
> diff --git a/src/dri2.c b/src/dri2.c
> index 3e5ee21..c8c0726 100644
> --- a/src/dri2.c
> +++ b/src/dri2.c
> @@ -69,6 +69,7 @@ typedef struct {
>  	struct list list;
>  	Display *dpy;
>  	const DRI2EventOps *ops;
> +	int major, minor;
>  } DRI2Display;
>  
>  static DRI2Display * dpy2dri(Display *dpy)
> @@ -201,6 +202,7 @@ Bool
>  DRI2QueryVersion(Display * dpy, int *major, int *minor)
>  {
>     XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +   DRI2Display *dri2dpy = dpy2dri(dpy);
>     xDRI2QueryVersionReply rep;
>     xDRI2QueryVersionReq *req;
>     int i, nevents;
> @@ -218,8 +220,8 @@ DRI2QueryVersion(Display * dpy, int *major, int *minor)
>        SyncHandle();
>        return False;
>     }
> -   *major = rep.majorVersion;
> -   *minor = rep.minorVersion;
> +   dri2dpy->major = *major = rep.majorVersion;
> +   dri2dpy->minor = *minor = rep.minorVersion;
>     UnlockDisplay(dpy);
>     SyncHandle();
>  
> @@ -365,10 +367,9 @@ DRI2DestroyDrawable(Display * dpy, XID drawable)
>     SyncHandle();
>  }
>  
> -DRI2Buffer *
> -DRI2GetBuffers(Display * dpy, XID drawable,
> -               int *width, int *height,
> -               unsigned int *attachments, int count, int *outCount)
> +static DRI2Buffer *
> +getbuffers(Display *dpy, XID drawable, int *width, int *height,
> +		unsigned int *attachments, int count, int *outCount, int dri2ReqType)
>  {
>     XExtDisplayInfo *info = DRI2FindDisplay(dpy);
>     xDRI2GetBuffersReply rep;
> @@ -376,18 +377,27 @@ DRI2GetBuffers(Display * dpy, XID drawable,
>     DRI2Buffer *buffers;
>     xDRI2Buffer repBuffer;
>     CARD32 *p;
> -   int i;
> +   int i, nattachments;
> +
> +   /* DRI2GetBuffersWithFormat has interleaved attachment+format in
> +    * attachments[] array, so length of array is 2x as long..
> +    */
> +   if (dri2ReqType == X_DRI2GetBuffersWithFormat) {
> +	   nattachments = 2 * count;
> +   } else {
> +	   nattachments = count;
> +   }
>  
>     XextCheckExtension(dpy, info, dri2ExtensionName, False);
>  
>     LockDisplay(dpy);
> -   GetReqExtra(DRI2GetBuffers, count * 4, req);
> +   GetReqExtra(DRI2GetBuffers, nattachments * 4, req);
>     req->reqType = info->codes->major_opcode;
> -   req->dri2ReqType = X_DRI2GetBuffers;
> +   req->dri2ReqType = dri2ReqType;
>     req->drawable = drawable;
>     req->count = count;
>     p = (CARD32 *) & req[1];
> -   for (i = 0; i < count; i++)
> +   for (i = 0; i < nattachments; i++)
>        p[i] = attachments[i];
>  
>     if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
> @@ -400,21 +410,16 @@ DRI2GetBuffers(Display * dpy, XID drawable,
>     *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;
> -   }
> -
> +   buffers = calloc(rep.count, sizeof buffers[0]);
>     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;
> +      if (buffers) {
> +         buffers[i].attachment = repBuffer.attachment;
> +         buffers[i].names[0] = repBuffer.name;
> +         buffers[i].pitch[0] = repBuffer.pitch;
> +         buffers[i].cpp = repBuffer.cpp;
> +         buffers[i].flags = repBuffer.flags;
> +      }
>     }



you check for OOM here what is good but i do  not see any action that is
done when OOM occurs. Atleast you should send an errormsg.
And the check is inside the loop ?


>     UnlockDisplay(dpy);
> @@ -423,65 +428,94 @@ DRI2GetBuffers(Display * dpy, XID drawable,
>     return buffers;
>  }
>  
> +DRI2Buffer *
> +DRI2GetBuffers(Display * dpy, XID drawable,
> +               int *width, int *height,
> +               unsigned int *attachments, int count, int *outCount)
> +{
> +	return getbuffers(dpy, drawable, width, height, attachments,
> +			count, outCount, X_DRI2GetBuffers);
> +}
>  
>  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;
> +	return getbuffers(dpy, drawable, width, height, attachments,
> +			count, outCount, X_DRI2GetBuffersWithFormat);
> +}
>  
> -   XextCheckExtension(dpy, info, dri2ExtensionName, False);
> +#ifdef X_DRI2GetBuffersVid
> +DRI2Buffer *
> +DRI2GetBuffersVid(Display * dpy, XID drawable,
> +               int width, int height,
> +               unsigned int *attachments, int count, int *outCount)
> +{
> +	XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +	DRI2Display *dri2dpy = dpy2dri(dpy);
> +	xDRI2GetBuffersReply rep;
> +	xDRI2GetBuffersVidReq *req;
> +	DRI2Buffer *buffers;
> +	xDRI2Buffer repBuffer;
> +	CARD32 *p;
> +	int i, nattachments = 2 * count;
>  
> -   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];
> +	XextCheckExtension(dpy, info, dri2ExtensionName, False);
>  
> -   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
> -      UnlockDisplay(dpy);
> -      SyncHandle();
> -      return NULL;
> -   }
> +    if (dri2dpy->minor < 4)
> +	return False;
>  
> -   *width = rep.width;
> -   *height = rep.height;
> -   *outCount = rep.count;
> +	LockDisplay(dpy);
> +	GetReqExtra(DRI2GetBuffersVid, nattachments * 4, req);
> +	req->reqType = info->codes->major_opcode;
> +	req->dri2ReqType = X_DRI2GetBuffersVid;
> +	req->drawable = drawable;
> +	req->width = width;
> +	req->height = height;
> +	req->count = count;
> +	p = (CARD32 *) & req[1];
> +	for (i = 0; i < nattachments; i++)
> +		p[i] = attachments[i];
> +
> +	if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
> +		UnlockDisplay(dpy);
> +		SyncHandle();
> +		return NULL;
> +	}
>  
> -   buffers = Xmalloc(rep.count * sizeof buffers[0]);
> -   if (buffers == NULL) {
> -      _XEatData(dpy, rep.count * sizeof repBuffer);
> -      UnlockDisplay(dpy);
> -      SyncHandle();
> -      return NULL;
> -   }
> +	*outCount = rep.count;
> +
> +	buffers = calloc(rep.count, sizeof buffers[0]);
> +	for (i = 0; i < rep.count; i++) {
> +		CARD32 n, j;
> +		_XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
> +		if (buffers) {
> +			buffers[i].attachment = repBuffer.attachment;
> +			buffers[i].names[0] = repBuffer.name;
> +			buffers[i].pitch[0] = repBuffer.pitch;
> +			buffers[i].cpp = repBuffer.cpp;
> +			buffers[i].flags = repBuffer.flags;
> +		}
>  


are you sure you want to check buffers inside the loop ?
It seems more logical to do this immediately after calloc()
or to ignore the check .



> -   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;
> -   }
> +		_XReadPad(dpy, (char *) &n, sizeof n);
> +		for (j = 0; j < n; j++) {
> +			CARD32 name, pitch;
> +			_XReadPad(dpy, (char *) &name, 4);
> +			_XReadPad(dpy, (char *) &pitch, 4);
> +			if (buffers) {
> +				buffers[i].names[j+1] = name;
> +				buffers[i].pitch[j+1] = pitch;
> +			}
> +		}
> +	}
>  
> -   UnlockDisplay(dpy);
> -   SyncHandle();
> +	UnlockDisplay(dpy);
> +	SyncHandle();
>  
> -   return buffers;
> +	return buffers;
>  }
> -
> +#endif
>  
>  void
>  DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
> @@ -552,6 +586,45 @@ void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
>  }
>  #endif
>  
> +#ifdef X_DRI2SwapBuffersVid
> +void DRI2SwapBuffersVid(Display *dpy, XID drawable, CARD64 target_msc,
> +		     CARD64 divisor, CARD64 remainder, CARD64 *count,
> +		     unsigned int source, BoxPtr b)
> +{
> +    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +    DRI2Display *dri2dpy = dpy2dri(dpy);
> +    xDRI2SwapBuffersVidReq *req;
> +    xDRI2SwapBuffersReply rep;
> +
> +    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
> +
> +    if (dri2dpy->minor < 4)
> +	return;
> +
> +    LockDisplay(dpy);
> +    GetReq(DRI2SwapBuffersVid, req);
> +    req->reqType = info->codes->major_opcode;
> +    req->dri2ReqType = X_DRI2SwapBuffersVid;
> +    req->drawable = drawable;
> +
> +    /* first part of message is same as original DRI2SwapBuffers.. */
> +    load_swap_req((xDRI2SwapBuffersReq *)req, target_msc, divisor, remainder);
> +
> +    req->source = source;
> +    req->x1 = b->x1;
> +    req->y1 = b->y1;
> +    req->x2 = b->x2;
> +    req->y2 = b->y2;
> +
> +    _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)
> @@ -690,3 +763,120 @@ void DRI2SwapInterval(Display *dpy, XID drawable, int interval)
>      SyncHandle();
>  }
>  #endif
> +
> +#ifdef X_DRI2SetAttribute
> +/* length in multiple of CARD32's */
> +void
> +DRI2SetAttribute(Display * dpy, XID drawable, Atom attribute,
> +		int len, const CARD32 *val)
> +{
> +    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +    DRI2Display *dri2dpy = dpy2dri(dpy);
> +    xDRI2SetAttributeReq *req;
> +
> +    XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
> +
> +    if (dri2dpy->minor < 4)
> +	return;
> +
> +    LockDisplay(dpy);
> +    GetReqExtra(DRI2SetAttribute, len * 4, req);
> +    req->reqType = info->codes->major_opcode;
> +    req->dri2ReqType = X_DRI2SetAttribute;
> +    req->drawable = drawable;
> +    req->attribute = attribute;
> +    memcpy(&req[1], val, len * 4);
> +    UnlockDisplay(dpy);
> +    SyncHandle();
> +}
> +#endif
> +
> +#ifdef X_DRI2GetAttribute
> +/* returned attribute should be free'd by caller.. length in multiple of
> + * CARD32's
> + */
> +Bool
> +DRI2GetAttribute(Display * dpy, XID drawable, Atom attribute,
> +		int *len, CARD32 **val)
> +{
> +    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +    DRI2Display *dri2dpy = dpy2dri(dpy);
> +    xDRI2GetAttributeReq *req;
> +    xDRI2GetAttributeReply rep;
> +
> +    XextCheckExtension (dpy, info, dri2ExtensionName, False);
> +
> +    if (dri2dpy->minor < 4)
> +	return False;
> +
> +    LockDisplay(dpy);
> +    GetReq(DRI2GetAttribute, req);
> +    req->reqType = info->codes->major_opcode;
> +    req->dri2ReqType = X_DRI2GetAttribute;
> +    req->drawable = drawable;
> +    req->attribute = attribute;
> +
> +    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
> +	UnlockDisplay(dpy);
> +	SyncHandle();
> +	return False;
> +    }
> +
> +    *len = rep.length;
> +    *val = malloc(rep.length * 4);
> +
> +    _XReadPad(dpy, (char *) *val, rep.length * 4);
> +
> +    UnlockDisplay(dpy);
> +    SyncHandle();
> +
> +    return True;
> +}
> +#endif
> +
> +#ifdef X_DRI2GetFormats
> +/* returned formats should be freed by caller */
> +Bool
> +DRI2GetFormats(Display * dpy, XID drawable, unsigned int *pnformats,
> +		unsigned int **pformats)
> +{
> +    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
> +    DRI2Display *dri2dpy = dpy2dri(dpy);
> +    xDRI2GetFormatsReq *req;
> +    xDRI2GetFormatsReply rep;
> +    unsigned int nformats, *formats;
> +    int i;
> +
> +    XextCheckExtension (dpy, info, dri2ExtensionName, False);
> +
> +    if (dri2dpy->minor < 4)
> +	return False;
> +
> +    LockDisplay(dpy);
> +    GetReq(DRI2GetFormats, req);
> +    req->reqType = info->codes->major_opcode;
> +    req->dri2ReqType = X_DRI2GetFormats;
> +    req->drawable = drawable;
> +
> +    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
> +	UnlockDisplay(dpy);
> +	SyncHandle();
> +	return False;
> +    }
> +
> +    nformats = (rep.length / sizeof(*formats)) * 4;

i do not understand the 4 here. do you mean:
  (rep.length / sizeof(*formats))*sizeof(*formats)

> +    formats = malloc(nformats * sizeof(*formats));

 calloc() ?


> +    for (i = 0; i < nformats; i++) {
> +	_XReadPad(dpy, (char *) &formats[i], sizeof(formats[i]));
> +    }
> +
> +    UnlockDisplay(dpy);
> +    SyncHandle();
> +
> +    *pnformats = nformats;
> +    *pformats = formats;
> +
> +    return True;
> +}
> +#endif
> diff --git a/test/Makefile.am b/test/Makefile.am
> index 8515c6b..fa48499 100644
> --- a/test/Makefile.am
> +++ b/test/Makefile.am
> @@ -1,4 +1,4 @@
> -lib_LTLIBRARIES = libdri2test.la
> +lib_LTLIBRARIES = libdri2test.la libdri2videotest.la
>  
>  COMMON_SOURCES = dri2util.c
>  COMMON_LIBADD  = @DRI2_LIBS@ 
> @@ -19,3 +19,7 @@ endif
>  libdri2test_la_SOURCES = dri2test.c $(COMMON_SOURCES)
>  libdri2test_la_LIBADD = $(COMMON_LIBADD)
>  libdri2test_la_CFLAGS = $(COMMON_CFLAGS)
> +
> +libdri2videotest_la_SOURCES = dri2videotest.c $(COMMON_SOURCES)
> +libdri2videotest_la_LIBADD = $(COMMON_LIBADD)
> +libdri2videotest_la_CFLAGS = $(COMMON_CFLAGS)
> diff --git a/test/dri2-nouveau.c b/test/dri2-nouveau.c
> index f91cc48..52de35e 100644
> --- a/test/dri2-nouveau.c
> +++ b/test/dri2-nouveau.c
> @@ -52,7 +52,7 @@ static void setup(int fd)
>  static void * init(DRI2Buffer *dri2buf)
>  {
>  	struct nouveau_bo *bo = NULL;
> -	int ret = nouveau_bo_handle_ref(dev, dri2buf->name, &bo);
> +	int ret = nouveau_bo_handle_ref(dev, dri2buf->names[0], &bo);
>  	if (ret) {
>  		ERROR_MSG("nouveau_bo_handle_ref failed: %d", ret);
>  		return NULL;
> diff --git a/test/dri2-omap.c b/test/dri2-omap.c
> index 181599d..2bcff28 100644
> --- a/test/dri2-omap.c
> +++ b/test/dri2-omap.c
> @@ -48,7 +48,7 @@ static void setup(int fd)
>  
>  static void * init(DRI2Buffer *dri2buf)
>  {
> -	return omap_bo_from_name(dev, dri2buf->name);
> +	return omap_bo_from_name(dev, dri2buf->names[0]);
>  }
>  
>  static char * prep(void *hdl)
> diff --git a/test/dri2test.c b/test/dri2test.c
> index 1aa101d..ec74e81 100644
> --- a/test/dri2test.c
> +++ b/test/dri2test.c
> @@ -48,7 +48,7 @@ static void fill(char *virtual, int n, int width, int height, int stride)
>      for (j = 0; j < height; j++) {
>              uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride);
>              for (i = 0; i < width; i++) {
> -                    div_t d = div(n+i, width);
> +                    div_t d = div(n+i+j, width);
>                      fb_ptr[i] =
>                              0x00130502 * (d.quot >> 6) +
>                              0x000a1120 * (d.rem >> 6);
> @@ -109,7 +109,7 @@ int main(int argc, char **argv)
>  		CARD64 count;
>  
>  		char *buf = backend->prep(bufs[i % nbufs].hdl);
> -		fill(buf, i, w, h, bufs[i % nbufs].dri2buf->pitch);
> +		fill(buf, i, w, h, bufs[i % nbufs].dri2buf->pitch[0]);
>  		backend->fini(bufs[i % nbufs].hdl);
>  		DRI2SwapBuffers(dpy, win, 0, 0, 0, &count);
>  		MSG("DRI2SwapBuffers: count=%lu", count);
> diff --git a/test/dri2videotest.c b/test/dri2videotest.c
> new file mode 100644
> index 0000000..c20141c
> --- /dev/null
> +++ b/test/dri2videotest.c
> @@ -0,0 +1,264 @@
> +/*
> + * Copyright © 2011 Texas Instruments, 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:
> + *   Rob Clark (rob at ti.com)
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#  include "config.h"
> +#endif
> +
> +#include <ctype.h>
> +
> +#include "dri2util.h"
> +
> +#define NFRAMES 300
> +#define WIN_WIDTH  500
> +#define WIN_HEIGHT 500
> +#define VID_WIDTH  1920
> +#define VID_HEIGHT 1080
> +
> +#define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 ))
> +#define FOURCC_STR(str)    FOURCC(str[0], str[1], str[2], str[3])
> +
> +/* swap these for big endian.. */
> +#define R 2
> +#define G 1
> +#define B 0

i know it is a test ... but could you replace that with RED,GREEN,BLUE, (or what ever ...)
single char defines tend to have unwanted consequences ....

> +
> +static void fill420(unsigned char *y, unsigned char *u, unsigned char *v,
> +		int cs /*chroma pixel stride */,
> +		int n, int width, int height, int stride)
> +{
> +	int i, j;
> +
> +	/* paint the buffer with colored tiles, in blocks of 2x2 */
> +	for (j = 0; j < height; j+=2) {
> +		unsigned char *y1p = y + j * stride;
> +		unsigned char *y2p = y1p + stride;
> +		unsigned char *up = u + (j/2) * stride * cs / 2;
> +		unsigned char *vp = v + (j/2) * stride * cs / 2;
> +
> +		for (i = 0; i < width; i+=2) {
> +			div_t d = div(n+i+j, width);
> +			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
> +			unsigned char *rgbp = &rgb;
> +			unsigned char y = (0.299 * rgbp[R]) + (0.587 * rgbp[G]) + (0.114 * rgbp[B]);
> +
> +			*(y2p++) = *(y1p++) = y;
> +			*(y2p++) = *(y1p++) = y;
> +
> +			*up = (rgbp[B] - y) * 0.565 + 128;
> +			*vp = (rgbp[R] - y) * 0.713 + 128;
> +			up += cs;
> +			vp += cs;
> +		}
> +	}
> +}
> +
> +static void fill422(unsigned char *virtual, int n, int width, int height, int stride)
> +{
> +	int i, j;
> +	/* paint the buffer with colored tiles */
> +	for (j = 0; j < height; j++) {
> +		uint8_t *ptr = (uint32_t*)((char*)virtual + j * stride);
> +		for (i = 0; i < width; i++) {
> +			div_t d = div(n+i+j, width);
> +			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
> +			unsigned char *rgbp = &rgb;
> +			unsigned char y = (0.299 * rgbp[R]) + (0.587 * rgbp[G]) + (0.114 * rgbp[B]);
> +
> +			*(ptr++) = y;
> +			*(ptr++) = (rgbp[B] - y) * 0.565 + 128;
> +			*(ptr++) = y;
> +			*(ptr++) = (rgbp[R] - y) * 0.713 + 128;
> +		}
> +	}
> +}
> +
> +/* stolen from modetest.c */
> +static void fill(unsigned char *virtual, int n, int width, int height, int stride)
> +{
> +	int i, j;
> +    /* paint the buffer with colored tiles */
> +    for (j = 0; j < height; j++) {
> +            uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride);
> +            for (i = 0; i < width; i++) {
> +                    div_t d = div(n+i+j, width);
> +                    fb_ptr[i] =
> +                            0x00130502 * (d.quot >> 6) +
> +                            0x000a1120 * (d.rem >> 6);
> +            }
> +    }
> +}
> +
> +
> +/* move this somewhere common?  It does seem useful.. */
> +static Bool is_fourcc(unsigned int val)
> +{
> +	char *str = (char *)&val;
> +	return isalnum(str[0]) && isalnum(str[1]) && isalnum(str[2]) && isalnum(str[3]);
> +}
> +
> +#define ATOM(name) XInternAtom(dpy, name, False)
> +
> +int main(int argc, char **argv)
> +{
> +	Display *dpy;
> +	Window win;
> +	Backend *backend = NULL;
> +	DRI2Buffer *dri2bufs;
> +	Buffer *bufs;
> +	char *driver;
> +	unsigned int nformats, *formats, format = 0;
> +	int fd, nbufs, i;
> +	CARD32 *pval;
> +
> +	dpy = XOpenDisplay(NULL);
> +	win = XCreateSimpleWindow(dpy, RootWindow(dpy, 0), 1, 1,
> +			WIN_WIDTH, WIN_HEIGHT, 0, BlackPixel (dpy, 0), BlackPixel(dpy, 0));
> +	XMapWindow(dpy, win);
> +	XFlush(dpy);
> +
> +	if ((fd = dri2_connect(dpy, DRI2DriverXV, &driver)) < 0) {
> +		return -1;
> +	}
> +
> +	if (!DRI2GetFormats(dpy, RootWindow(dpy, DefaultScreen(dpy)),
> +			&nformats, &formats)) {
> +		ERROR_MSG("DRI2GetFormats failed");
> +		return -1;
> +	}
> +
> +	if (nformats == 0) {
> +		ERROR_MSG("no formats!");
> +		return -1;
> +	}
> +
> +	/* print out supported formats */
> +	MSG("Found %d supported formats:", nformats);
> +	for (i = 0; i < nformats; i++) {
> +		if (is_fourcc(formats[i])) {
> +			MSG("  %d: %08x (\"%.4s\")", i, formats[i], (char *)&formats[i]);
> +		} else {
> +			MSG("  %d: %08x (device dependent)", i, formats[i]);
> +		}
> +	}
> +
> +	// XXX pick something we understand!
> +//	format = FOURCC_STR("I420");
> +	format = FOURCC_STR("YUY2");
> +//	format = FOURCC_STR("RGB4");
> +
> +	free(formats);
> +
> +	backend = get_backend(driver);
> +	if (!backend) {
> +		return -1;
> +	}
> +
> +	backend->setup(fd);
> +
> +	DRI2CreateDrawable(dpy, win);
> +
> +	/* check some attribute.. just to exercise the code-path: */
> +	if (!DRI2GetAttribute(dpy, win, ATOM("XV_CSC_MATRIX"), &i, &pval)) {
> +		ERROR_MSG("DRI2GetAttribute failed");
> +		return -1;
> +	}
> +

This seems the only the only place where ATOM() is used.
Perhaps you can drop that define ?
re,
 wh


> +	MSG("Got CSC matrix:");
> +	print_hex(i*4, (const unsigned char *)pval);
> +
> +	free(pval);
> +
> +	unsigned attachments[] = {
> +			DRI2BufferFrontLeft, 32, /* always requested, never returned */
> +			1, format, 2, format, 3, format, 4, format,
> +	};
> +	dri2bufs = DRI2GetBuffersVid(dpy, win, VID_WIDTH, VID_HEIGHT, attachments, 4, &nbufs);
> +	if (!dri2bufs) {
> +		ERROR_MSG("DRI2GetBuffersVid failed");
> +		return -1;
> +	}
> +
> +	MSG("DRI2GetBuffers: nbufs=%d", nbufs);
> +
> +	bufs = calloc(nbufs, sizeof(Buffer));
> +
> +	for (i = 0; i < nbufs; i++) {
> +		bufs[i].dri2buf = &dri2bufs[i];
> +		bufs[i].hdl = backend->init(bufs[i].dri2buf);
> +	}
> +
> +	for (i = 0; i < NFRAMES; i++) {
> +		BoxRec b = {
> +				// TODO change this dynamically..  fill appropriately so
> +				// the cropped region has different color, or something,
> +				// so we can see visually if cropping is incorrect..
> +				.x1 = 0,
> +				.y1 = 0,
> +				.x2 = VID_WIDTH,
> +				.y2 = VID_HEIGHT,
> +		};
> +		CARD64 count;
> +
> +		Buffer *buf = &bufs[i % nbufs];
> +		int pitch = buf->dri2buf->pitch[0];
> +		unsigned char *ptr = backend->prep(buf->hdl);
> +		if (format == FOURCC_STR("I420")) {
> +#if 0
> +			unsigned char *y = ptr;
> +			// XXX deal with multiple bo case
> +			unsigned char *u = y + (VID_HEIGHT * pitch);
> +			unsigned char *v = u + (VID_HEIGHT * pitch) / 4;
> +			fill420(y, u, v, 1, i, VID_WIDTH, VID_HEIGHT, pitch);
> +#else
> +			/* I think the nouveau shader actually expects NV12... */
> +			unsigned char *y = ptr;
> +			// XXX deal with multiple bo case
> +			unsigned char *u = y + (VID_HEIGHT * pitch);
> +			unsigned char *v = u + 1;
> +			fill420(y, u, v, 2, i, VID_WIDTH, VID_HEIGHT, pitch);
> +#endif
> +		} else if (format == FOURCC_STR("YUY2")) {
> +			fill422(ptr, i, VID_WIDTH, VID_HEIGHT, pitch);
> +		} else if (format == FOURCC_STR("RGB4")) {
> +			fill(ptr, i, VID_WIDTH, VID_HEIGHT, pitch);
> +		}
> +		backend->fini(buf->hdl);
> +		DRI2SwapBuffersVid(dpy, win, 0, 0, 0, &count, (i % nbufs) + 1, &b);
> +		MSG("DRI2SwapBuffersVid: count=%lu", count);
> +		if (i > 0) {
> +			/* XXX wait.. */
> +		}
> +	}
> +
> +	return 0;
> +}


More information about the xorg-devel mailing list