summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/X11/va_x11.c2
-rw-r--r--src/dri1_util.c158
-rw-r--r--src/dri2_util.c198
-rw-r--r--src/va.c24
-rwxr-xr-xsrc/va_backend.h9
-rw-r--r--src/va_dricommon.c62
-rw-r--r--src/va_dricommon.h68
8 files changed, 519 insertions, 6 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8af43f2..a4d9e6b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,7 +42,7 @@ va_version.h: Makefile
SUBDIRS = X11
-libva_la_SOURCES = va.c
+libva_la_SOURCES = va.c va_dricommon.c dri2_util.c dri1_util.c
libvaincludedir = ${includedir}/va
-libvainclude_HEADERS = va.h va_backend.h
+libvainclude_HEADERS = va.h va_backend.h va_dricommon.h
diff --git a/src/X11/va_x11.c b/src/X11/va_x11.c
index 85b21d5..4cb8fcd 100644
--- a/src/X11/va_x11.c
+++ b/src/X11/va_x11.c
@@ -28,6 +28,7 @@
#include "va_x11.h"
#include "va_dri.h"
#include "va_dri2.h"
+#include "va_dricommon.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
@@ -289,6 +290,7 @@ VADisplay vaGetDisplay (
pDisplayContext->vaDestroy = va_DisplayContextDestroy;
pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
pDisplayContexts = pDisplayContext;
+ pDriverContext->dri_state = calloc(1, sizeof(struct dri_state));
dpy = (VADisplay)pDisplayContext;
}
else
diff --git a/src/dri1_util.c b/src/dri1_util.c
new file mode 100644
index 0000000..b3db5b4
--- /dev/null
+++ b/src/dri1_util.c
@@ -0,0 +1,158 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+#include <xf86drm.h>
+
+#include "X11/Xlib.h"
+#include "va.h"
+#include "va_backend.h"
+
+#include "va_dri.h"
+#include "va_dricommon.h"
+
+struct dri1_drawable
+{
+ struct dri_drawable base;
+ union dri_buffer buffer;
+ int width;
+ int height;
+};
+
+static struct dri_drawable *
+dri1CreateDrawable(VADriverContextP ctx, XID x_drawable)
+{
+ struct dri1_drawable *dri1_drawable;
+
+ dri1_drawable = calloc(1, sizeof(*dri1_drawable));
+
+ if (!dri1_drawable)
+ return NULL;
+
+ dri1_drawable->base.x_drawable = x_drawable;
+
+ return &dri1_drawable->base;
+}
+
+static void
+dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ free(dri_drawable);
+}
+
+static void
+dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+
+}
+
+static union dri_buffer *
+dri1GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ struct dri1_drawable *dri1_drawable = (struct dri1_drawable *)dri_drawable;
+
+ return &dri1_drawable->buffer;
+}
+
+static void
+dri1Close(VADriverContextP ctx)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+
+ free_drawable_hashtable(ctx);
+ VA_DRIDestroyContext(ctx->x11_dpy, ctx->x11_screen, dri_state->hwContextID);
+ assert(dri_state->pSAREA != MAP_FAILED);
+ drmUnmap(dri_state->pSAREA, SAREA_MAX);
+ assert(dri_state->fd >= 0);
+ drmCloseOnce(dri_state->fd);
+ VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen);
+}
+
+Bool
+isDRI1Connected(VADriverContextP ctx, char **driver_name)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+ int direct_capable;
+ int driver_major;
+ int driver_minor;
+ int driver_patch;
+ int newlyopened;
+ char *BusID;
+ drm_magic_t magic;
+
+ *driver_name = NULL;
+ dri_state->fd = -1;
+ dri_state->pSAREA = MAP_FAILED;
+ dri_state->driConnectedFlag = VA_NONE;
+
+ if (!VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy,
+ ctx->x11_screen,
+ &direct_capable))
+ goto err_out0;
+
+ if (!direct_capable)
+ goto err_out0;
+
+ if (!VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen,
+ &driver_major, &driver_minor,
+ &driver_patch, driver_name))
+ goto err_out0;
+
+ if (!VA_DRIOpenConnection(ctx->x11_dpy, ctx->x11_screen,
+ &dri_state->hSAREA, &BusID))
+ goto err_out0;
+
+
+ dri_state->fd = drmOpenOnce(NULL, BusID, &newlyopened);
+ XFree(BusID);
+ assert(dri_state->fd >= 0);
+
+ if (dri_state->fd < 0)
+ goto err_out1;
+
+
+ if (drmGetMagic(dri_state->fd, &magic))
+ goto err_out1;
+
+ if (newlyopened && !VA_DRIAuthConnection(ctx->x11_dpy, ctx->x11_screen, magic))
+ goto err_out1;
+
+ if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
+ goto err_out1;
+
+ if (!VA_DRICreateContext(ctx->x11_dpy, ctx->x11_screen,
+ DefaultVisual(ctx->x11_dpy, ctx->x11_screen),
+ &dri_state->hwContextID, &dri_state->hwContext))
+ goto err_out1;
+
+ dri_state->driConnectedFlag = VA_DRI1;
+ dri_state->createDrawable = dri1CreateDrawable;
+ dri_state->destroyDrawable = dri1DestroyDrawable;
+ dri_state->swapBuffer = dri1SwapBuffer;
+ dri_state->getRenderingBuffer = dri1GetRenderingBuffer;
+ dri_state->close = dri1Close;
+
+ return True;
+
+err_out1:
+ if (dri_state->pSAREA != MAP_FAILED)
+ drmUnmap(dri_state->pSAREA, SAREA_MAX);
+
+ if (dri_state->fd >= 0)
+ drmCloseOnce(dri_state->fd);
+
+ VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen);
+
+err_out0:
+ if (*driver_name)
+ XFree(*driver_name);
+
+ dri_state->pSAREA = MAP_FAILED;
+ dri_state->fd = -1;
+ *driver_name = NULL;
+
+ return False;
+}
+
diff --git a/src/dri2_util.c b/src/dri2_util.c
new file mode 100644
index 0000000..7ed168d
--- /dev/null
+++ b/src/dri2_util.c
@@ -0,0 +1,198 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <xf86drm.h>
+
+#include "X11/Xlib.h"
+#include "va.h"
+#include "va_backend.h"
+
+#include "va_dri2.h"
+#include "va_dricommon.h"
+
+#define __DRI_BUFFER_FRONT_LEFT 0
+#define __DRI_BUFFER_BACK_LEFT 1
+#define __DRI_BUFFER_FRONT_RIGHT 2
+#define __DRI_BUFFER_BACK_RIGHT 3
+#define __DRI_BUFFER_DEPTH 4
+#define __DRI_BUFFER_STENCIL 5
+#define __DRI_BUFFER_ACCUM 6
+#define __DRI_BUFFER_FAKE_FRONT_LEFT 7
+#define __DRI_BUFFER_FAKE_FRONT_RIGHT 8
+
+struct dri2_drawable
+{
+ struct dri_drawable base;
+ union dri_buffer buffers[5];
+ int width;
+ int height;
+ int has_backbuffer;
+ int back_index;
+ int front_index;
+};
+
+static struct dri_drawable *
+dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
+{
+ struct dri2_drawable *dri2_drawable;
+
+ dri2_drawable = calloc(1, sizeof(*dri2_drawable));
+
+ if (!dri2_drawable)
+ return NULL;
+
+ dri2_drawable->base.x_drawable = x_drawable;
+ dri2_drawable->base.x = 0;
+ dri2_drawable->base.y = 0;
+ DRI2CreateDrawable(ctx->x11_dpy, x_drawable);
+
+ return &dri2_drawable->base;
+}
+
+static void
+dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ DRI2DestroyDrawable(ctx->x11_dpy, dri_drawable->x_drawable);
+ free(dri_drawable);
+}
+
+static void
+dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
+ XRectangle xrect;
+ XserverRegion region;
+
+ if (dri2_drawable->has_backbuffer) {
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = dri2_drawable->width;
+ xrect.height = dri2_drawable->height;
+
+ region = XFixesCreateRegion(ctx->x11_dpy, &xrect, 1);
+ DRI2CopyRegion(ctx->x11_dpy, dri_drawable->x_drawable, region,
+ DRI2BufferFrontLeft, DRI2BufferBackLeft);
+ XFixesDestroyRegion(ctx->x11_dpy, region);
+ }
+}
+
+static union dri_buffer *
+dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
+ int i;
+ int count;
+ unsigned int attachments[5];
+ DRI2Buffer *buffers;
+
+ i = 0;
+ attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+ attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+ buffers = DRI2GetBuffers(ctx->x11_dpy, dri_drawable->x_drawable,
+ &dri2_drawable->width, &dri2_drawable->height,
+ attachments, i, &count);
+ assert(buffers);
+ if (buffers == NULL)
+ return NULL;
+
+ dri2_drawable->has_backbuffer = 0;
+
+ for (i = 0; i < count; i++) {
+ dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment;
+ dri2_drawable->buffers[i].dri2.name = buffers[i].name;
+ dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch;
+ dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp;
+ dri2_drawable->buffers[i].dri2.flags = buffers[i].flags;
+
+ if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) {
+ dri2_drawable->has_backbuffer = 1;
+ dri2_drawable->back_index = i;
+ }
+
+ if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
+ dri2_drawable->front_index = i;
+ }
+
+ dri_drawable->width = dri2_drawable->width;
+ dri_drawable->height = dri2_drawable->height;
+ Xfree(buffers);
+
+ if (dri2_drawable->has_backbuffer)
+ return &dri2_drawable->buffers[dri2_drawable->back_index];
+
+ return &dri2_drawable->buffers[dri2_drawable->front_index];
+}
+
+static void
+dri2Close(VADriverContextP ctx)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+
+ free_drawable_hashtable(ctx);
+ assert(dri_state->fd >= 0);
+ close(dri_state->fd);
+}
+
+Bool
+isDRI2Connected(VADriverContextP ctx, char **driver_name)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+ int major, minor;
+ int error_base;
+ int event_base;
+ char *device_name = NULL;
+ drm_magic_t magic;
+ *driver_name = NULL;
+ dri_state->fd = -1;
+ dri_state->driConnectedFlag = VA_NONE;
+ if (!DRI2QueryExtension(ctx->x11_dpy, &event_base, &error_base))
+ goto err_out;
+
+ if (!DRI2QueryVersion(ctx->x11_dpy, &major, &minor))
+ goto err_out;
+
+
+ if (!DRI2Connect(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen),
+ driver_name, &device_name))
+ goto err_out;
+
+ dri_state->fd = open(device_name, O_RDWR);
+ assert(dri_state->fd >= 0);
+
+ if (dri_state->fd < 0)
+ goto err_out;
+
+ if (drmGetMagic(dri_state->fd, &magic))
+ goto err_out;
+
+ if (!DRI2Authenticate(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen),
+ magic))
+ goto err_out;
+
+ dri_state->driConnectedFlag = VA_DRI2;
+ dri_state->createDrawable = dri2CreateDrawable;
+ dri_state->destroyDrawable = dri2DestroyDrawable;
+ dri_state->swapBuffer = dri2SwapBuffer;
+ dri_state->getRenderingBuffer = dri2GetRenderingBuffer;
+ dri_state->close = dri2Close;
+
+ return True;
+
+err_out:
+ if (device_name)
+ Xfree(device_name);
+
+ if (*driver_name)
+ Xfree(*driver_name);
+
+ if (dri_state->fd >= 0)
+ close(dri_state->fd);
+
+ *driver_name = NULL;
+ dri_state->fd = -1;
+
+ return False;
+}
+
diff --git a/src/va.c b/src/va.c
index fe6e1bd..de2d2d8 100644
--- a/src/va.c
+++ b/src/va.c
@@ -35,6 +35,10 @@
#include <unistd.h>
#include <linux/videodev2.h>
+#include "va_dri.h"
+#include "va_dri2.h"
+#include "va_dricommon.h"
+
#define VA_STR_VERSION VA_BUILD_DATE VA_BUILD_GIT
@@ -112,7 +116,21 @@ static Bool va_checkString(const char* value, char *variable)
static VAStatus va_getDriverName(VADisplay dpy, char **driver_name)
{
VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
- return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
+ VADriverContextP ctx = CTX(dpy);
+
+ VAStatus ret;
+ ret = pDisplayContext->vaGetDriverName(pDisplayContext, driver_name);
+ if (ret == VA_STATUS_SUCCESS)
+ {
+ if (isDRI2Connected(ctx, driver_name))
+ {
+ ret = VA_STATUS_SUCCESS;
+ } else if (isDRI1Connected(ctx, driver_name))
+ {
+ ret = VA_STATUS_SUCCESS;
+ }
+ }
+ return ret;
}
static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
@@ -137,8 +155,8 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name)
search_path = DEFAULT_DRIVER_DIR;
}
- search_path = strdup(search_path);
- driver_dir = strtok_r(search_path, ":", &saveptr);
+ search_path = strdup((const char *)search_path);
+ driver_dir = strtok_r((const char *)search_path, ":", &saveptr);
while(driver_dir)
{
void *handle = NULL;
diff --git a/src/va_backend.h b/src/va_backend.h
index f8456ad..09b0e2c 100755
--- a/src/va_backend.h
+++ b/src/va_backend.h
@@ -297,7 +297,12 @@ struct VADriverVTable
VASubpictureID subpicture,
VAImageID image
);
-
+
+ VAStatus (*vaSetSubpicturePalette) (
+ VADriverContextP ctx,
+ VASubpictureID subpicture,
+ unsigned char *palette);
+
VAStatus (*vaSetSubpictureChromakey) (
VADriverContextP ctx,
VASubpictureID subpicture,
@@ -426,6 +431,8 @@ struct VADriverContext
const char *str_vendor;
void *handle; /* dlopen handle */
+
+ void *dri_state;
};
struct VADisplayContext
diff --git a/src/va_dricommon.c b/src/va_dricommon.c
new file mode 100644
index 0000000..f9c3dfd
--- /dev/null
+++ b/src/va_dricommon.c
@@ -0,0 +1,62 @@
+#include "va_dricommon.h"
+
+static struct dri_drawable *
+do_drawable_hash(VADriverContextP ctx, XID drawable)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+ int index = drawable % DRAWABLE_HASH_SZ;
+ struct dri_drawable *dri_drawable = dri_state->drawable_hash[index];
+
+ while (dri_drawable) {
+ if (dri_drawable->x_drawable == drawable)
+ return dri_drawable;
+ dri_drawable = dri_drawable->next;
+ }
+
+ dri_drawable = dri_state->createDrawable(ctx, drawable);
+ dri_drawable->x_drawable = drawable;
+ dri_drawable->next = dri_state->drawable_hash[index];
+ dri_state->drawable_hash[index] = dri_drawable;
+
+ return dri_drawable;
+}
+
+void
+free_drawable_hashtable(VADriverContextP ctx)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+ int i;
+ struct dri_drawable *dri_drawable, *prev;
+
+ for (i = 0; i < DRAWABLE_HASH_SZ; i++) {
+ dri_drawable = dri_state->drawable_hash[i];
+
+ while (dri_drawable) {
+ prev = dri_drawable;
+ dri_drawable = prev->next;
+ dri_state->destroyDrawable(ctx, prev);
+ }
+ }
+}
+
+struct dri_drawable *
+dri_get_drawable(VADriverContextP ctx, XID drawable)
+{
+ return do_drawable_hash(ctx, drawable);
+}
+
+void
+dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+
+ dri_state->swapBuffer(ctx, dri_drawable);
+}
+
+union dri_buffer *
+dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
+{
+ struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+
+ return dri_state->getRenderingBuffer(ctx, dri_drawable);
+}
diff --git a/src/va_dricommon.h b/src/va_dricommon.h
new file mode 100644
index 0000000..a2a51a6
--- /dev/null
+++ b/src/va_dricommon.h
@@ -0,0 +1,68 @@
+#ifndef _VA_DRICOMMON_H_
+#define _VA_DRICOMMON_H_
+
+#include <X11/Xlib.h>
+
+#include <xf86drm.h>
+#include <drm.h>
+#include <drm_sarea.h>
+
+#include "va_backend.h"
+
+enum
+{
+ VA_NONE = 0,
+ VA_DRI1 = 1,
+ VA_DRI2 = 2
+};
+
+union dri_buffer
+{
+ struct {
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+ } dri2;
+
+ struct {
+ } dri1;
+};
+
+struct dri_drawable
+{
+ XID x_drawable;
+ int x;
+ int y;
+ unsigned int width;
+ unsigned int height;
+ struct dri_drawable *next;
+};
+
+#define DRAWABLE_HASH_SZ 32
+struct dri_state
+{
+ int fd;
+ int driConnectedFlag; /* 0: disconnected, 1: DRI, 2: DRI2 */
+ drm_handle_t hSAREA;
+ drm_context_t hwContext;
+ drmAddress pSAREA;
+ XID hwContextID;
+ struct dri_drawable *drawable_hash[DRAWABLE_HASH_SZ];
+
+ struct dri_drawable *(*createDrawable)(VADriverContextP ctx, XID x_drawable);
+ void (*destroyDrawable)(VADriverContextP ctx, struct dri_drawable *dri_drawable);
+ void (*swapBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable);
+ union dri_buffer *(*getRenderingBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable);
+ void (*close)(VADriverContextP ctx);
+};
+
+Bool isDRI2Connected(VADriverContextP ctx, char **driver_name);
+Bool isDRI1Connected(VADriverContextP ctx, char **driver_name);
+void free_drawable_hashtable(VADriverContextP ctx);
+struct dri_drawable *dri_get_drawable(VADriverContextP ctx, XID drawable);
+void dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable);
+union dri_buffer *dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable);
+
+#endif /* _VA_DRICOMMON_H_ */