#include #include #include #include #include #include #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((Display *)ctx->native_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((Display *)ctx->native_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((Display *)ctx->native_dpy, ctx->x11_screen, &direct_capable)) goto err_out0; if (!direct_capable) goto err_out0; if (!VA_DRIGetClientDriverName((Display *)ctx->native_dpy, ctx->x11_screen, &driver_major, &driver_minor, &driver_patch, driver_name)) goto err_out0; if (!VA_DRIOpenConnection((Display *)ctx->native_dpy, ctx->x11_screen, &dri_state->hSAREA, &BusID)) goto err_out0; dri_state->fd = drmOpenOnce(NULL, BusID, &newlyopened); XFree(BusID); if (dri_state->fd < 0) goto err_out1; if (drmGetMagic(dri_state->fd, &magic)) goto err_out1; if (newlyopened && !VA_DRIAuthConnection((Display *)ctx->native_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((Display *)ctx->native_dpy, ctx->x11_screen, DefaultVisual((Display *)ctx->native_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((Display *)ctx->native_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; }