dri1_util.c revision 5b3d55a0433b48477823f81821817a78ef53ac2e
1#include <stdlib.h>
2#include <fcntl.h>
3#include <unistd.h>
4#include <sys/mman.h>
5#include <assert.h>
6
7#include <xf86drm.h>
8
9#include "X11/Xlib.h"
10#include "va.h"
11#include "va_backend.h"
12
13#include "va_dri.h"
14#include "va_dricommon.h"
15
16struct dri1_drawable
17{
18    struct dri_drawable base;
19    union dri_buffer buffer;
20    int width;
21    int height;
22};
23
24static struct dri_drawable *
25dri1CreateDrawable(VADriverContextP ctx, XID x_drawable)
26{
27    struct dri1_drawable *dri1_drawable;
28
29    dri1_drawable = calloc(1, sizeof(*dri1_drawable));
30
31    if (!dri1_drawable)
32        return NULL;
33
34    dri1_drawable->base.x_drawable = x_drawable;
35
36    return &dri1_drawable->base;
37}
38
39static void
40dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
41{
42    free(dri_drawable);
43}
44
45static void
46dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
47{
48
49}
50
51static union dri_buffer *
52dri1GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
53{
54    struct dri1_drawable *dri1_drawable = (struct dri1_drawable *)dri_drawable;
55
56    return &dri1_drawable->buffer;
57}
58
59static void
60dri1Close(VADriverContextP ctx)
61{
62    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
63
64    free_drawable_hashtable(ctx);
65    VA_DRIDestroyContext(ctx->native_dpy, ctx->x11_screen, dri_state->hwContextID);
66    assert(dri_state->pSAREA != MAP_FAILED);
67    drmUnmap(dri_state->pSAREA, SAREA_MAX);
68    assert(dri_state->fd >= 0);
69    drmCloseOnce(dri_state->fd);
70    VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);
71}
72
73Bool
74isDRI1Connected(VADriverContextP ctx, char **driver_name)
75{
76    struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
77    int direct_capable;
78    int driver_major;
79    int driver_minor;
80    int driver_patch;
81    int newlyopened;
82    char *BusID;
83    drm_magic_t magic;
84
85    *driver_name = NULL;
86    dri_state->fd = -1;
87    dri_state->pSAREA = MAP_FAILED;
88    dri_state->driConnectedFlag = VA_NONE;
89
90    if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy,
91                                           ctx->x11_screen,
92                                           &direct_capable))
93        goto err_out0;
94
95    if (!direct_capable)
96        goto err_out0;
97
98    if (!VA_DRIGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
99                                   &driver_major, &driver_minor,
100                                   &driver_patch, driver_name))
101        goto err_out0;
102
103    if (!VA_DRIOpenConnection(ctx->native_dpy, ctx->x11_screen,
104                              &dri_state->hSAREA, &BusID))
105        goto err_out0;
106
107
108    dri_state->fd = drmOpenOnce(NULL, BusID, &newlyopened);
109    XFree(BusID);
110
111    if (dri_state->fd < 0)
112        goto err_out1;
113
114
115    if (drmGetMagic(dri_state->fd, &magic))
116        goto err_out1;
117
118    if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic))
119        goto err_out1;
120
121    if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
122        goto err_out1;
123
124    if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen,
125                             DefaultVisual(ctx->native_dpy, ctx->x11_screen),
126                             &dri_state->hwContextID, &dri_state->hwContext))
127        goto err_out1;
128
129    dri_state->driConnectedFlag = VA_DRI1;
130    dri_state->createDrawable = dri1CreateDrawable;
131    dri_state->destroyDrawable = dri1DestroyDrawable;
132    dri_state->swapBuffer = dri1SwapBuffer;
133    dri_state->getRenderingBuffer = dri1GetRenderingBuffer;
134    dri_state->close = dri1Close;
135
136    return True;
137
138err_out1:
139    if (dri_state->pSAREA != MAP_FAILED)
140        drmUnmap(dri_state->pSAREA, SAREA_MAX);
141
142    if (dri_state->fd >= 0)
143        drmCloseOnce(dri_state->fd);
144
145    VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);
146
147err_out0:
148    if (*driver_name)
149        XFree(*driver_name);
150
151    dri_state->pSAREA = MAP_FAILED;
152    dri_state->fd = -1;
153    *driver_name = NULL;
154
155    return False;
156}
157
158