OSDN Git Service

Display *x11_dpy ==> void *native_dpy for other window system
[android-x86/hardware-intel-common-libva.git] / va / x11 / dri2_util.c
1 #include <stdlib.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <assert.h>
5
6 #include <xf86drm.h>
7
8 #include <X11/Xlibint.h>
9 #include <X11/Xlib.h>
10 #include "va.h"
11 #include "va_backend.h"
12
13 #include "va_dri2.h"
14 #include "va_dri2tokens.h"
15 #include "va_dricommon.h"
16
17 #define __DRI_BUFFER_FRONT_LEFT         0
18 #define __DRI_BUFFER_BACK_LEFT          1
19 #define __DRI_BUFFER_FRONT_RIGHT        2
20 #define __DRI_BUFFER_BACK_RIGHT         3
21 #define __DRI_BUFFER_DEPTH              4
22 #define __DRI_BUFFER_STENCIL            5
23 #define __DRI_BUFFER_ACCUM              6
24 #define __DRI_BUFFER_FAKE_FRONT_LEFT    7
25 #define __DRI_BUFFER_FAKE_FRONT_RIGHT   8
26
27 struct dri2_drawable 
28 {
29     struct dri_drawable base;
30     union dri_buffer buffers[5];
31     int width;
32     int height;
33     int has_backbuffer;
34     int back_index;
35     int front_index;
36 };
37
38 static struct dri_drawable * 
39 dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
40 {
41     struct dri2_drawable *dri2_drawable;
42
43     dri2_drawable = calloc(1, sizeof(*dri2_drawable));
44
45     if (!dri2_drawable)
46         return NULL;
47
48     dri2_drawable->base.x_drawable = x_drawable;
49     dri2_drawable->base.x = 0;
50     dri2_drawable->base.y = 0;
51     VA_DRI2CreateDrawable((Display *)ctx->native_dpy, x_drawable);
52
53     return &dri2_drawable->base;
54 }
55
56 static void 
57 dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
58 {
59     VA_DRI2DestroyDrawable((Display *)ctx->native_dpy, dri_drawable->x_drawable);
60     free(dri_drawable);
61 }
62
63 static void 
64 dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
65 {
66     struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
67     XRectangle xrect;
68     XserverRegion region;
69
70     if (dri2_drawable->has_backbuffer) {
71         xrect.x = 0;
72         xrect.y = 0;
73         xrect.width = dri2_drawable->width;
74         xrect.height = dri2_drawable->height;
75
76         region = XFixesCreateRegion((Display *)ctx->native_dpy, &xrect, 1);
77         VA_DRI2CopyRegion((Display *)ctx->native_dpy, dri_drawable->x_drawable, region,
78                        DRI2BufferFrontLeft, DRI2BufferBackLeft);
79         XFixesDestroyRegion((Display *)ctx->native_dpy, region);
80     }
81 }
82
83 static union dri_buffer *
84 dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
85 {
86     struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
87     int i;
88     int count;
89     unsigned int attachments[5];
90     VA_DRI2Buffer *buffers;
91     
92     i = 0;
93     attachments[i++] = __DRI_BUFFER_BACK_LEFT;
94     attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
95     buffers = VA_DRI2GetBuffers((Display *)ctx->native_dpy, dri_drawable->x_drawable,
96                              &dri2_drawable->width, &dri2_drawable->height, 
97                              attachments, i, &count);
98     assert(buffers);
99     if (buffers == NULL)
100         return NULL;
101
102     dri2_drawable->has_backbuffer = 0;
103
104     for (i = 0; i < count; i++) {
105         dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment;
106         dri2_drawable->buffers[i].dri2.name = buffers[i].name;
107         dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch;
108         dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp;
109         dri2_drawable->buffers[i].dri2.flags = buffers[i].flags;
110         
111         if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) {
112             dri2_drawable->has_backbuffer = 1;
113             dri2_drawable->back_index = i;
114         }
115
116         if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
117             dri2_drawable->front_index = i;
118     }
119     
120     dri_drawable->width = dri2_drawable->width;
121     dri_drawable->height = dri2_drawable->height;
122     Xfree(buffers);
123
124     if (dri2_drawable->has_backbuffer)
125         return &dri2_drawable->buffers[dri2_drawable->back_index];
126
127     return &dri2_drawable->buffers[dri2_drawable->front_index];
128 }
129
130 static void
131 dri2Close(VADriverContextP ctx)
132 {
133     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
134
135     free_drawable_hashtable(ctx);
136     assert(dri_state->fd >= 0);
137     close(dri_state->fd);
138 }
139
140 Bool 
141 isDRI2Connected(VADriverContextP ctx, char **driver_name)
142 {
143     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
144     int major, minor;
145     int error_base;
146     int event_base;
147     char *device_name = NULL;
148     drm_magic_t magic;        
149     *driver_name = NULL;
150     dri_state->fd = -1;
151     dri_state->driConnectedFlag = VA_NONE;
152     if (!VA_DRI2QueryExtension((Display *)ctx->native_dpy, &event_base, &error_base))
153         goto err_out;
154
155     if (!VA_DRI2QueryVersion((Display *)ctx->native_dpy, &major, &minor))
156         goto err_out;
157
158
159     if (!VA_DRI2Connect((Display *)ctx->native_dpy, RootWindow((Display *)ctx->native_dpy, ctx->x11_screen),
160                      driver_name, &device_name))
161         goto err_out;
162
163     dri_state->fd = open(device_name, O_RDWR);
164     assert(dri_state->fd >= 0);
165
166     if (dri_state->fd < 0)
167         goto err_out;
168
169     if (drmGetMagic(dri_state->fd, &magic))
170         goto err_out;
171
172     if (!VA_DRI2Authenticate((Display *)ctx->native_dpy, RootWindow((Display *)ctx->native_dpy, ctx->x11_screen),
173                           magic))
174         goto err_out;
175
176     dri_state->driConnectedFlag = VA_DRI2;
177     dri_state->createDrawable = dri2CreateDrawable;
178     dri_state->destroyDrawable = dri2DestroyDrawable;
179     dri_state->swapBuffer = dri2SwapBuffer;
180     dri_state->getRenderingBuffer = dri2GetRenderingBuffer;
181     dri_state->close = dri2Close;
182
183     return True;
184
185 err_out:
186     if (device_name)
187         Xfree(device_name);
188
189     if (*driver_name)
190         Xfree(*driver_name);
191
192     if (dri_state->fd >= 0)
193         close(dri_state->fd);
194
195     *driver_name = NULL;
196     dri_state->fd = -1;
197     
198     return False;
199 }
200