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 struct dri_drawable *
39 dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
41 struct dri2_drawable *dri2_drawable;
43 dri2_drawable = calloc(1, sizeof(*dri2_drawable));
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);
53 return &dri2_drawable->base;
57 dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
59 VA_DRI2DestroyDrawable((Display *)ctx->native_dpy, dri_drawable->x_drawable);
64 dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
66 struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
70 if (dri2_drawable->has_backbuffer) {
73 xrect.width = dri2_drawable->width;
74 xrect.height = dri2_drawable->height;
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);
83 static union dri_buffer *
84 dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
86 struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
89 unsigned int attachments[5];
90 VA_DRI2Buffer *buffers;
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);
102 dri2_drawable->has_backbuffer = 0;
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;
111 if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) {
112 dri2_drawable->has_backbuffer = 1;
113 dri2_drawable->back_index = i;
116 if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
117 dri2_drawable->front_index = i;
120 dri_drawable->width = dri2_drawable->width;
121 dri_drawable->height = dri2_drawable->height;
124 if (dri2_drawable->has_backbuffer)
125 return &dri2_drawable->buffers[dri2_drawable->back_index];
127 return &dri2_drawable->buffers[dri2_drawable->front_index];
131 dri2Close(VADriverContextP ctx)
133 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
135 free_drawable_hashtable(ctx);
136 assert(dri_state->fd >= 0);
137 close(dri_state->fd);
141 isDRI2Connected(VADriverContextP ctx, char **driver_name)
143 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
147 char *device_name = NULL;
151 dri_state->driConnectedFlag = VA_NONE;
152 if (!VA_DRI2QueryExtension((Display *)ctx->native_dpy, &event_base, &error_base))
155 if (!VA_DRI2QueryVersion((Display *)ctx->native_dpy, &major, &minor))
159 if (!VA_DRI2Connect((Display *)ctx->native_dpy, RootWindow((Display *)ctx->native_dpy, ctx->x11_screen),
160 driver_name, &device_name))
163 dri_state->fd = open(device_name, O_RDWR);
164 assert(dri_state->fd >= 0);
166 if (dri_state->fd < 0)
169 if (drmGetMagic(dri_state->fd, &magic))
172 if (!VA_DRI2Authenticate((Display *)ctx->native_dpy, RootWindow((Display *)ctx->native_dpy, ctx->x11_screen),
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;
192 if (dri_state->fd >= 0)
193 close(dri_state->fd);