Merge branch 'master' of ssh://git@moblin.intel.com/umg-moorestown-libva
[profile/ivi/libva.git] / va / x11 / dri1_util.c
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
16 struct dri1_drawable 
17 {
18     struct dri_drawable base;
19     union dri_buffer buffer;
20     int width;
21     int height;
22 };
23
24 static struct dri_drawable * 
25 dri1CreateDrawable(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
39 static void 
40 dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
41 {
42     free(dri_drawable);
43 }
44
45 static void 
46 dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
47 {
48
49 }
50
51 static union dri_buffer *
52 dri1GetRenderingBuffer(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
59 static void
60 dri1Close(VADriverContextP ctx)
61 {
62     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
63
64     free_drawable_hashtable(ctx);
65     VA_DRIDestroyContext((Display *)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((Display *)ctx->native_dpy, ctx->x11_screen);
71 }
72
73 Bool 
74 isDRI1Connected(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((Display *)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((Display *)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((Display *)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((Display *)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((Display *)ctx->native_dpy, ctx->x11_screen,
125                              DefaultVisual((Display *)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
138 err_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((Display *)ctx->native_dpy, ctx->x11_screen);
146
147 err_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