summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4f1eef3)
raw | patch | inline | side by side (parent: 4f1eef3)
author | Rob Clark <rob.clark@linaro.org> | |
Sat, 21 Jan 2012 17:29:37 +0000 (11:29 -0600) | ||
committer | Nikhil Devshatwar <a0132237@ti.com> | |
Thu, 16 May 2013 14:10:07 +0000 (19:40 +0530) |
Makefile.am | patch | blob | history | |
include/X11/extensions/dri2.h | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/dri2.c | patch | blob | history | |
test/Makefile.am | patch | blob | history | |
test/dri2videotest.c | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile.am b/Makefile.am
index 4a7b6a14c6efc4e0d6bbb306ad8098d14f042474..d4ce9466b8ede3d8cb34104572455e0a83068798 100644 (file)
--- a/Makefile.am
+++ b/Makefile.am
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
index 71c73341635435f18d0a959d8c7fe71a2fd590a7..b15620cee80bf248ade43836b8561ea5a5d8a2bb 100644 (file)
#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 *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,
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);
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 07f249278ea7ae17bb02fac8fd6c1c78aa3e0869..ac3494afa8cd1cf97444e34246c46cf77cb9b8a2 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
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 f94736c9f99c845405b3e16681c8c598239fa173..e08caefe1fd7dace80b174970facb10d151e3105 100644 (file)
--- a/src/dri2.c
+++ b/src/dri2.c
struct list list;
Display *dpy;
const DRI2EventOps *ops;
+ int major, minor;
} DRI2Display;
static DRI2Display * dpy2dri(Display *dpy)
DRI2QueryVersion(Display * dpy, int *major, int *minor)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ DRI2Display *dri2dpy = dpy2dri(dpy);
xDRI2QueryVersionReply rep;
xDRI2QueryVersionReq *req;
int i, nevents;
SyncHandle();
return False;
}
- *major = rep.majorVersion;
- *minor = rep.minorVersion;
+ dri2dpy->major = *major = rep.majorVersion;
+ dri2dpy->minor = *minor = rep.minorVersion;
UnlockDisplay(dpy);
SyncHandle();
static DRI2Buffer *
getbuffers(Display *dpy, XID drawable, int *width, int *height,
- unsigned int *attachments, int count, int *outCount, int dri2ReqType)
+ unsigned int *attachments, int count, int *outCount, int dri2ReqType)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2GetBuffersReply rep;
int *width, int *height,
unsigned int *attachments, int count, int *outCount)
{
- return getbuffers(dpy, drawable, width, height, attachments,
- count, outCount, X_DRI2GetBuffers);
+ return getbuffers(dpy, drawable, width, height, attachments,
+ count, outCount, X_DRI2GetBuffers);
}
DRI2Buffer *
int *width, int *height,
unsigned int *attachments, int count, int *outCount)
{
- return getbuffers(dpy, drawable, width, height, attachments,
- count, outCount, X_DRI2GetBuffersWithFormat);
+ return getbuffers(dpy, drawable, width, height, attachments,
+ count, outCount, X_DRI2GetBuffersWithFormat);
}
+#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;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ if (dri2dpy->minor < 4)
+ return False;
+
+ 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;
+ }
+
+ *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;
+ }
+
+ _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();
+
+ return buffers;
+}
+#endif
void
DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
}
#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)
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 * 4 / sizeof(*formats);
+ formats = malloc(nformats * sizeof(*formats));
+
+ 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 bfafadd2a2aa120b00089ff6603ea9cbd1273216..ce5004f824e5babb610cffe2494ac05ec9b57741 100644 (file)
--- a/test/Makefile.am
+++ b/test/Makefile.am
-noinst_LTLIBRARIES = libdri2test.la
+noinst_LTLIBRARIES = libdri2test.la libdri2videotest.la
COMMON_SOURCES = dri2util.c
COMMON_LIBADD = @DRI2_LIBS@
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/dri2videotest.c b/test/dri2videotest.c
--- /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@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 RED 2
+#define GREEN 1
+#define BLUE 0
+
+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[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
+
+ *(y2p++) = *(y1p++) = y;
+ *(y2p++) = *(y1p++) = y;
+
+ *up = (rgbp[BLUE] - y) * 0.565 + 128;
+ *vp = (rgbp[RED] - 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+=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[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
+
+ *(ptr++) = y;
+ *(ptr++) = (rgbp[BLUE] - y) * 0.565 + 128;
+ *(ptr++) = y;
+ *(ptr++) = (rgbp[RED] - 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;
+ }
+
+ 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;
+}