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 (r...@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; > +} _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel