dri_screen_t *dri_screen;
dri_framebuffer_t dri_framebuf;
struct dri1_api *api_hooks;
+ boolean dri2;
};
struct vl_dri_context
int fd;
struct pipe_video_context *vpipe;
dri_drawable_t *drawable;
+ struct pipe_surface *dri2_front;
};
static void
static void
vl_clip_copy(struct vl_dri_context *vl_dri_ctx,
- struct pipe_surface *dst,
- struct pipe_surface *src,
- const struct drm_clip_rect *src_bbox)
+ struct pipe_surface *dst,
+ struct pipe_surface *src,
+ const struct drm_clip_rect *src_bbox)
{
- struct pipe_video_context *vpipe = vl_dri_ctx->base.vpipe;
+ struct pipe_video_context *vpipe;
struct drm_clip_rect clip;
struct drm_clip_rect *cur;
int i;
assert(src);
assert(src_bbox);
+ vpipe = vl_dri_ctx->base.vpipe;
+
assert(vl_dri_ctx->drawable->cliprects);
assert(vl_dri_ctx->drawable->num_cliprects > 0);
vl_dri_update_drawables_locked(vl_dri_ctx);
- src_bbox.x1 = 0;
- src_bbox.x2 = vl_dri_ctx->drawable->w;
- src_bbox.y1 = 0;
- src_bbox.y2 = vl_dri_ctx->drawable->h;
+ if (vl_dri_ctx->drawable->cliprects) {
+ src_bbox.x1 = 0;
+ src_bbox.x2 = vl_dri_ctx->drawable->w;
+ src_bbox.y1 = 0;
+ src_bbox.y2 = vl_dri_ctx->drawable->h;
#if 0
- if (vl_dri_scrn->_api_hooks->present_locked)
- vl_dri_scrn->api_hooks->present_locked(pipe, surf,
- vl_dri_ctx->drawable->cliprects,
- vl_dri_ctx->drawable->num_cliprects,
- vl_dri_ctx->drawable->x, vl_dri_drawable->y,
- &bbox, NULL /*fence*/);
- else
+ if (vl_dri_scrn->_api_hooks->present_locked)
+ vl_dri_scrn->api_hooks->present_locked(pipe, surf,
+ vl_dri_ctx->drawable->cliprects,
+ vl_dri_ctx->drawable->num_cliprects,
+ vl_dri_ctx->drawable->x, vl_dri_drawable->y,
+ &bbox, NULL /*fence*/);
+ else
#endif
- if (vl_dri_scrn->api_hooks->front_srf_locked) {
- struct pipe_surface *front = vl_dri_scrn->api_hooks->front_srf_locked(screen);
+ if (vl_dri_scrn->api_hooks->front_srf_locked) {
+ struct pipe_surface *front = vl_dri_scrn->api_hooks->front_srf_locked(screen);
- if (front)
- vl_clip_copy(vl_dri_ctx, front, surf, &src_bbox);
+ if (front)
+ vl_clip_copy(vl_dri_ctx, front, surf, &src_bbox);
- //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
+ //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
+ }
}
vl_dri_ctx->lost_lock = save_lost_lock;
vl_dri_unlock(vl_dri_ctx);
}
+static struct pipe_surface*
+vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
+{
+ int w, h;
+ unsigned int attachments[1] = {DRI_BUFFER_FRONT_LEFT};
+ int count;
+ DRI2Buffer *dri2_front;
+ struct pipe_resource template, *front_tex;
+ struct pipe_surface *front_surf = NULL;
+
+ assert(vl_dri_scrn);
+
+ dri2_front = DRI2GetBuffers(vl_dri_scrn->dri_screen->display,
+ drawable, &w, &h, attachments, 1, &count);
+ if (dri2_front) {
+ struct winsys_handle dri2_front_handle =
+ {
+ .type = DRM_API_HANDLE_TYPE_SHARED,
+ .handle = dri2_front->name,
+ .stride = dri2_front->pitch
+ };
+ front_tex = vl_dri_scrn->base.pscreen->resource_from_handle(vl_dri_scrn->base.pscreen, &template, &dri2_front_handle);
+ if (front_tex)
+ front_surf = vl_dri_scrn->base.pscreen->get_tex_surface(vl_dri_scrn->base.pscreen,
+ front_tex, 0, 0, 0,
+ /*PIPE_BIND_RENDER_TARGET*/ PIPE_BIND_BLIT_DESTINATION);
+ pipe_resource_reference(&front_tex, NULL);
+ }
+
+ return front_surf;
+}
+
+static void
+vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf, void *context_private)
+{
+ struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private;
+ struct vl_dri_screen *vl_dri_scrn;
+ struct pipe_video_context *vpipe;
+
+ assert(screen);
+ assert(surf);
+ assert(context_private);
+ assert(vl_dri_ctx->dri2_front);
+
+ vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
+ vpipe = vl_dri_ctx->base.vpipe;
+
+ /* XXX: Why not just render to fake front? */
+ vpipe->surface_copy(vpipe, vl_dri_ctx->dri2_front, 0, 0, surf, 0, 0, surf->width, surf->height);
+
+ //st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
+}
+
+
Drawable
vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable)
{
if (vl_dri_ctx->drawable)
old_drawable = vl_dri_ctx->drawable->x_drawable;
- vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
- driCreateDrawable(vl_dri_scrn->dri_screen, drawable, &dri_drawable);
- vl_dri_ctx->drawable = dri_drawable;
+ if (drawable != old_drawable) {
+ vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
+ if (vl_dri_scrn->dri2) {
+ /* XXX: Need dri2CreateDrawable()? */
+ vl_dri_ctx->dri2_front = vl_dri2_get_front(vl_dri_scrn, drawable);
+ }
+ else {
+ driCreateDrawable(vl_dri_scrn->dri_screen, drawable, &dri_drawable);
+ vl_dri_ctx->drawable = dri_drawable;
+ }
+ }
return old_drawable;
}
if (!vl_dri_scrn)
return NULL;
- driCreateScreen(display, screen, &vl_dri_scrn->dri_screen, &vl_dri_scrn->dri_framebuf);
- vl_dri_scrn->api = drm_api_create();
+ /* Try DRI2 first */
+ if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen)) {
+ /* If not, try DRI */
+ if (driCreateScreen(display, screen, &vl_dri_scrn->dri_screen, &vl_dri_scrn->dri_framebuf)) {
+ /* Now what? */
+ FREE(vl_dri_scrn);
+ return NULL;
+ }
+ else {
+ /* Got DRI */
+ arg.base.mode = DRM_CREATE_DRI1;
+ arg.lf = &dri1_lf;
+ arg.ddx_info = vl_dri_scrn->dri_framebuf.private;
+ arg.ddx_info_size = vl_dri_scrn->dri_framebuf.private_size;
+ arg.sarea = vl_dri_scrn->dri_screen->sarea;
+ vl_dri_copy_version(&arg.ddx_version, &vl_dri_scrn->dri_screen->ddx);
+ vl_dri_copy_version(&arg.dri_version, &vl_dri_scrn->dri_screen->dri);
+ vl_dri_copy_version(&arg.drm_version, &vl_dri_scrn->dri_screen->drm);
+ arg.api = NULL;
+ vl_dri_scrn->dri2 = FALSE;
+ }
+ }
+ else {
+ /* Got DRI2 */
+ arg.base.mode = DRM_CREATE_NORMAL;
+ vl_dri_scrn->dri2 = TRUE;
+ }
- arg.base.mode = DRM_CREATE_DRI1;
- arg.lf = &dri1_lf;
- arg.ddx_info = vl_dri_scrn->dri_framebuf.private;
- arg.ddx_info_size = vl_dri_scrn->dri_framebuf.private_size;
- arg.sarea = vl_dri_scrn->dri_screen->sarea;
- vl_dri_copy_version(&arg.ddx_version, &vl_dri_scrn->dri_screen->ddx);
- vl_dri_copy_version(&arg.dri_version, &vl_dri_scrn->dri_screen->dri);
- vl_dri_copy_version(&arg.drm_version, &vl_dri_scrn->dri_screen->drm);
- arg.api = NULL;
+ vl_dri_scrn->api = drm_api_create();
+ if (!vl_dri_scrn->api) {
+ FREE(vl_dri_scrn);
+ return NULL;
+ }
vl_dri_scrn->base.pscreen = vl_dri_scrn->api->create_screen(vl_dri_scrn->api,
vl_dri_scrn->dri_screen->fd,
return NULL;
}
- vl_dri_scrn->visual = XDefaultVisual(display, screen);
- vl_dri_scrn->api_hooks = arg.api;
- vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri_flush_frontbuffer;
- /* XXX: Safe to call this while unlocked? */
- vl_dri_scrn->base.format = vl_dri_scrn->api_hooks->front_srf_locked(vl_dri_scrn->base.pscreen)->format;
+ if (!vl_dri_scrn->dri2) {
+ vl_dri_scrn->visual = XDefaultVisual(display, screen);
+ vl_dri_scrn->api_hooks = arg.api;
+ vl_dri_scrn->base.format = vl_dri_scrn->api_hooks->front_srf_locked(vl_dri_scrn->base.pscreen)->format;
+ vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri_flush_frontbuffer;
+ }
+ else
+ vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
return &vl_dri_scrn->base;
}
assert(vscreen);
vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
- driDestroyScreen(vl_dri_scrn->dri_screen);
+ if (vl_dri_scrn->dri2)
+ dri2DestroyScreen(vl_dri_scrn->dri_screen);
+ else
+ driDestroyScreen(vl_dri_scrn->dri_screen);
FREE(vl_dri_scrn);
}
return NULL;
/* XXX: Is default visual correct/sufficient here? */
- driCreateContext(vl_dri_scrn->dri_screen, vl_dri_scrn->visual, &vl_dri_ctx->dri_context);
+ if (!vl_dri_scrn->dri2)
+ driCreateContext(vl_dri_scrn->dri_screen, vl_dri_scrn->visual, &vl_dri_ctx->dri_context);
- if (!vl_dri_scrn->api->create_video_context) {
+ if (!vscreen->pscreen->video_context_create) {
debug_printf("[G3DVL] No video support found on %s/%s.\n",
- vl_dri_scrn->base.pscreen->get_vendor(vl_dri_scrn->base.pscreen),
- vl_dri_scrn->base.pscreen->get_name(vl_dri_scrn->base.pscreen));
+ vscreen->pscreen->get_vendor(vscreen->pscreen),
+ vscreen->pscreen->get_name(vscreen->pscreen));
FREE(vl_dri_ctx);
return NULL;
}
- vl_dri_ctx->base.vpipe = vl_dri_scrn->api->create_video_context(vl_dri_scrn->api,
- vscreen->pscreen,
+ vl_dri_ctx->base.vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen,
profile, chroma_format,
- width, height);
+ width, height,
+ vl_dri_ctx->dri_context);
if (!vl_dri_ctx->base.vpipe) {
FREE(vl_dri_ctx);
vl_dri_ctx->base.vpipe->priv = vl_dri_ctx;
vl_dri_ctx->base.vscreen = vscreen;
vl_dri_ctx->fd = vl_dri_scrn->dri_screen->fd;
- vl_dri_ctx->lock = (drmLock*)&vl_dri_scrn->dri_screen->sarea->lock;
+ if (!vl_dri_scrn->dri2)
+ vl_dri_ctx->lock = (drmLock*)&vl_dri_scrn->dri_screen->sarea->lock;
return &vl_dri_ctx->base;
}
assert(vctx);
vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe);
+ if (!((struct vl_dri_screen *)vctx->vscreen)->dri2)
+ driDestroyContext(vl_dri_ctx->dri_context);
FREE(vl_dri_ctx);
}