8 #include <X11/Xlibint.h>
11 #include "va_backend.h"
14 #include "va_dri2tokens.h"
15 #include "va_dricommon.h"
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
29 struct dri_drawable base;
30 union dri_buffer buffers[5];
38 static int gsDRI2SwapAvailable;
40 static struct dri_drawable *
41 dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
43 struct dri2_drawable *dri2_drawable;
45 dri2_drawable = calloc(1, sizeof(*dri2_drawable));
50 dri2_drawable->base.x_drawable = x_drawable;
51 dri2_drawable->base.x = 0;
52 dri2_drawable->base.y = 0;
53 VA_DRI2CreateDrawable(ctx->native_dpy, x_drawable);
55 return &dri2_drawable->base;
59 dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
61 VA_DRI2DestroyDrawable(ctx->native_dpy, dri_drawable->x_drawable);
66 dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
68 struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
72 if (dri2_drawable->has_backbuffer) {
73 if (gsDRI2SwapAvailable) {
75 VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable, 0, 0,
80 xrect.width = dri2_drawable->width;
81 xrect.height = dri2_drawable->height;
83 region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1);
84 VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region,
85 DRI2BufferFrontLeft, DRI2BufferBackLeft);
86 XFixesDestroyRegion(ctx->native_dpy, region);
91 static union dri_buffer *
92 dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
94 struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
97 unsigned int attachments[5];
98 VA_DRI2Buffer *buffers;
101 if (dri_drawable->is_window)
102 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
104 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
106 buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable,
107 &dri2_drawable->width, &dri2_drawable->height,
108 attachments, i, &count);
113 dri2_drawable->has_backbuffer = 0;
115 for (i = 0; i < count; i++) {
116 dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment;
117 dri2_drawable->buffers[i].dri2.name = buffers[i].name;
118 dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch;
119 dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp;
120 dri2_drawable->buffers[i].dri2.flags = buffers[i].flags;
122 if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) {
123 dri2_drawable->has_backbuffer = 1;
124 dri2_drawable->back_index = i;
127 if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
128 dri2_drawable->front_index = i;
131 dri_drawable->width = dri2_drawable->width;
132 dri_drawable->height = dri2_drawable->height;
135 if (dri2_drawable->has_backbuffer)
136 return &dri2_drawable->buffers[dri2_drawable->back_index];
138 return &dri2_drawable->buffers[dri2_drawable->front_index];
142 dri2Close(VADriverContextP ctx)
144 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
146 free_drawable_hashtable(ctx);
148 if (dri_state->fd >= 0);
149 close(dri_state->fd);
153 isDRI2Connected(VADriverContextP ctx, char **driver_name)
155 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
159 char *device_name = NULL;
163 dri_state->driConnectedFlag = VA_NONE;
164 if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base))
167 if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor))
171 if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
172 driver_name, &device_name))
175 dri_state->fd = open(device_name, O_RDWR);
176 assert(dri_state->fd >= 0);
178 if (dri_state->fd < 0)
181 if (drmGetMagic(dri_state->fd, &magic))
184 if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
188 dri_state->driConnectedFlag = VA_DRI2;
189 dri_state->createDrawable = dri2CreateDrawable;
190 dri_state->destroyDrawable = dri2DestroyDrawable;
191 dri_state->swapBuffer = dri2SwapBuffer;
192 dri_state->getRenderingBuffer = dri2GetRenderingBuffer;
193 dri_state->close = dri2Close;
194 gsDRI2SwapAvailable = (minor >= 2);
208 if (dri_state->fd >= 0)
209 close(dri_state->fd);