5 #include <X11/Xlibint.h>
7 int driCreateScreen(Display
*display
, int screen
, dri_screen_t
**dri_screen
, dri_framebuffer_t
*dri_framebuf
)
13 drmVersionPtr drm_version
;
14 drm_handle_t sarea_handle
;
16 dri_screen_t
*dri_scrn
;
21 if (!XF86DRIQueryExtension(display
, &evbase
, &errbase
))
24 dri_scrn
= calloc(1, sizeof(dri_screen_t
));
29 if (!XF86DRIQueryVersion(display
, &dri_scrn
->dri
.major
, &dri_scrn
->dri
.minor
, &dri_scrn
->dri
.patch
))
32 dri_scrn
->display
= display
;
33 dri_scrn
->num
= screen
;
34 dri_scrn
->draw_lock_id
= 1;
36 if (!XF86DRIOpenConnection(display
, screen
, &sarea_handle
, &bus_id
))
40 dri_scrn
->fd
= drmOpenOnce(NULL
, bus_id
, &newly_opened
);
44 goto close_connection
;
46 if (drmGetMagic(dri_scrn
->fd
, &magic
))
49 drm_version
= drmGetVersion(dri_scrn
->fd
);
54 dri_scrn
->drm
.major
= drm_version
->version_major
;
55 dri_scrn
->drm
.minor
= drm_version
->version_minor
;
56 dri_scrn
->drm
.patch
= drm_version
->version_patchlevel
;
57 drmFreeVersion(drm_version
);
59 if (!XF86DRIAuthConnection(display
, screen
, magic
))
62 if (!XF86DRIGetClientDriverName
73 if (drmMap(dri_scrn
->fd
, sarea_handle
, SAREA_MAX
, (drmAddress
)&dri_scrn
->sarea
))
76 dri_scrn
->drawable_hash
= drmHashCreate();
78 if (!dri_scrn
->drawable_hash
)
83 if (!XF86DRIGetDeviceInfo
86 screen
, &dri_framebuf
->drm_handle
,
89 &dri_framebuf
->stride
,
90 &dri_framebuf
->private_size
,
91 &dri_framebuf
->private
96 *dri_screen
= dri_scrn
;
101 drmHashDestroy(dri_scrn
->drawable_hash
);
103 drmUnmap(dri_scrn
->sarea
, SAREA_MAX
);
105 drmCloseOnce(dri_scrn
->fd
);
107 XF86DRICloseConnection(display
, screen
);
114 int driDestroyScreen(dri_screen_t
*dri_screen
)
117 dri_drawable_t
*dri_draw
;
121 if (drmHashFirst(dri_screen
->drawable_hash
, &draw
, (void**)&dri_draw
))
123 dri_draw
->refcount
= 1;
124 driDestroyDrawable(dri_draw
);
126 while (drmHashNext(dri_screen
->drawable_hash
, &draw
, (void**)&dri_draw
))
128 dri_draw
->refcount
= 1;
129 driDestroyDrawable(dri_draw
);
133 drmHashDestroy(dri_screen
->drawable_hash
);
134 drmUnmap(dri_screen
->sarea
, SAREA_MAX
);
135 drmCloseOnce(dri_screen
->fd
);
136 XF86DRICloseConnection(dri_screen
->display
, dri_screen
->num
);
142 int driCreateDrawable(dri_screen_t
*dri_screen
, Drawable drawable
, dri_drawable_t
**dri_drawable
)
145 dri_drawable_t
*dri_draw
;
148 assert(dri_drawable
);
150 if (!XF86DRIQueryExtension(dri_screen
->display
, &evbase
, &errbase
))
153 if (!drmHashLookup(dri_screen
->drawable_hash
, drawable
, (void**)dri_drawable
))
156 (*dri_drawable
)->refcount
++;
160 dri_draw
= calloc(1, sizeof(dri_drawable_t
));
165 if (!XF86DRICreateDrawable(dri_screen
->display
, 0, drawable
, &dri_draw
->drm_drawable
))
171 dri_draw
->x_drawable
= drawable
;
172 dri_draw
->sarea_index
= 0;
173 dri_draw
->sarea_stamp
= NULL
;
174 dri_draw
->last_sarea_stamp
= 0;
175 dri_draw
->dri_screen
= dri_screen
;
176 dri_draw
->refcount
= 1;
178 if (drmHashInsert(dri_screen
->drawable_hash
, drawable
, dri_draw
))
180 XF86DRIDestroyDrawable(dri_screen
->display
, dri_screen
->num
, drawable
);
185 if (!dri_draw
->sarea_stamp
|| *dri_draw
->sarea_stamp
!= dri_draw
->last_sarea_stamp
)
187 DRM_SPINLOCK(&dri_screen
->sarea
->drawable_lock
, dri_screen
->draw_lock_id
);
189 if (driUpdateDrawableInfo(dri_draw
))
191 XF86DRIDestroyDrawable(dri_screen
->display
, dri_screen
->num
, drawable
);
193 DRM_SPINUNLOCK(&dri_screen
->sarea
->drawable_lock
, dri_screen
->draw_lock_id
);
197 DRM_SPINUNLOCK(&dri_screen
->sarea
->drawable_lock
, dri_screen
->draw_lock_id
);
200 *dri_drawable
= dri_draw
;
205 int driUpdateDrawableInfo(dri_drawable_t
*dri_drawable
)
207 assert(dri_drawable
);
209 if (dri_drawable
->cliprects
)
211 XFree(dri_drawable
->cliprects
);
212 dri_drawable
->cliprects
= NULL
;
214 if (dri_drawable
->back_cliprects
)
216 XFree(dri_drawable
->back_cliprects
);
217 dri_drawable
->back_cliprects
= NULL
;
220 DRM_SPINUNLOCK(&dri_drawable
->dri_screen
->sarea
->drawable_lock
, dri_drawable
->dri_screen
->draw_lock_id
);
222 if (!XF86DRIGetDrawableInfo
224 dri_drawable
->dri_screen
->display
,
225 dri_drawable
->dri_screen
->num
,
226 dri_drawable
->x_drawable
,
227 &dri_drawable
->sarea_index
,
228 &dri_drawable
->last_sarea_stamp
,
233 &dri_drawable
->num_cliprects
,
234 &dri_drawable
->cliprects
,
235 &dri_drawable
->back_x
,
236 &dri_drawable
->back_y
,
237 &dri_drawable
->num_back_cliprects
,
238 &dri_drawable
->back_cliprects
241 dri_drawable
->sarea_stamp
= &dri_drawable
->last_sarea_stamp
;
242 dri_drawable
->num_cliprects
= 0;
243 dri_drawable
->cliprects
= NULL
;
244 dri_drawable
->num_back_cliprects
= 0;
245 dri_drawable
->back_cliprects
= 0;
250 dri_drawable
->sarea_stamp
= &dri_drawable
->dri_screen
->sarea
->drawableTable
[dri_drawable
->sarea_index
].stamp
;
252 DRM_SPINLOCK(&dri_drawable
->dri_screen
->sarea
->drawable_lock
, dri_drawable
->dri_screen
->draw_lock_id
);
257 int driDestroyDrawable(dri_drawable_t
*dri_drawable
)
259 assert(dri_drawable
);
261 if (--dri_drawable
->refcount
== 0)
263 if (dri_drawable
->cliprects
)
264 XFree(dri_drawable
->cliprects
);
265 if (dri_drawable
->back_cliprects
)
266 XFree(dri_drawable
->back_cliprects
);
267 drmHashDelete(dri_drawable
->dri_screen
->drawable_hash
, dri_drawable
->x_drawable
);
268 XF86DRIDestroyDrawable(dri_drawable
->dri_screen
->display
, dri_drawable
->dri_screen
->num
, dri_drawable
->x_drawable
);
275 int driCreateContext(dri_screen_t
*dri_screen
, Visual
*visual
, dri_context_t
**dri_context
)
278 dri_context_t
*dri_ctx
;
284 if (!XF86DRIQueryExtension(dri_screen
->display
, &evbase
, &errbase
))
287 dri_ctx
= calloc(1, sizeof(dri_context_t
));
292 if (!XF86DRICreateContext(dri_screen
->display
, dri_screen
->num
, visual
, &dri_ctx
->id
, &dri_ctx
->drm_context
))
298 dri_ctx
->dri_screen
= dri_screen
;
299 *dri_context
= dri_ctx
;
304 int driDestroyContext(dri_context_t
*dri_context
)
308 XF86DRIDestroyContext(dri_context
->dri_screen
->display
, dri_context
->dri_screen
->num
, dri_context
->id
);
314 int dri2CreateScreen(Display
*display
, int screen
, dri_screen_t
**dri_screen
)
316 dri_screen_t
*dri_scrn
;
321 dri_scrn
= calloc(1, sizeof(dri_screen_t
));
326 if (!DRI2Connect(display
, XRootWindow(display
, screen
), &drvName
, &devName
))
329 dri_scrn
->fd
= open(devName
, O_RDWR
);
332 if (dri_scrn
->fd
< 0)
335 if (drmGetMagic(dri_scrn
->fd
, &magic
))
338 if (!DRI2Authenticate(display
, RootWindow(display
, screen
), magic
))
341 dri_scrn
->display
= display
;
342 dri_scrn
->num
= screen
;
343 *dri_screen
= dri_scrn
;
353 int dri2DestroyScreen(dri_screen_t
*dri_screen
)
355 /* Not much to do here apparently... */
359 int dri2CreateDrawable(dri_screen_t
*dri_screen
, XID drawable
)
361 DRI2CreateDrawable(dri_screen
->display
, drawable
);
365 int dri2DestroyDrawable(dri_screen_t
*dri_screen
, XID drawable
)
367 DRI2DestroyDrawable(dri_screen
->display
, drawable
);