For DRI swap buffers.

This commit added two APIs to support the DRI swap buffer.
one is glamor_egl_exchange_buffers() which can swap two
pixmaps' underlying KHRimages/fbos/texs. The DDX layer should
exchange the DRM bos to make them consistent to each other.

Another API is glamor_egl_create_textured_screen_ext(), which
extent one more parameters to track the DDX layer's back pixmap
pointer. This is for the triple buffer support. When using triple
buffer, the DDX layer will keep a back pixmap rather then the
front pixmap and the pixmap used by the DRI2 client. And during
the closing screen stage, we have to dereference all the back
pixmap's glamor resources. Thus we have to extent this API to
register it when create new screen.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2012-02-17 16:56:05 +08:00 committed by Eric Anholt
parent 8012b030c3
commit 213285f2b8
5 changed files with 129 additions and 19 deletions

View File

@ -106,7 +106,7 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
}
void
glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap)
{
glamor_pixmap_private *pixmap_priv;
glamor_screen_private *glamor_priv;
@ -117,6 +117,8 @@ glamor_set_screen_pixmap(PixmapPtr screen_pixmap)
pixmap_priv->fbo->width = screen_pixmap->drawable.width;
pixmap_priv->fbo->height = screen_pixmap->drawable.height;
glamor_priv->back_pixmap = back_pixmap;
}
PixmapPtr
@ -420,6 +422,29 @@ glamor_release_screen_priv(ScreenPtr screen)
glamor_set_screen_private(screen, NULL);
}
_X_EXPORT void
glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
{
glamor_pixmap_private *old_priv;
glamor_pixmap_fbo *fbo;
old_priv = dixGetPrivate(&pixmap->devPrivates, glamor_pixmap_private_key);
if (priv) {
assert(old_priv == NULL);
} else {
if (old_priv == NULL)
return;
fbo = glamor_pixmap_detach_fbo(old_priv);
glamor_purge_fbo(fbo);
free(old_priv);
}
dixSetPrivate(&pixmap->devPrivates,
glamor_pixmap_private_key,
priv);
}
Bool
glamor_close_screen(int idx, ScreenPtr screen)
{
@ -458,9 +483,10 @@ glamor_close_screen(int idx, ScreenPtr screen)
}
#endif
screen_pixmap = screen->GetScreenPixmap(screen);
screen_pixmap_priv = glamor_get_pixmap_private(screen_pixmap);
fbo = glamor_pixmap_detach_fbo(screen_pixmap_priv);
glamor_purge_fbo(fbo);
glamor_set_pixmap_private(screen_pixmap, NULL);
if (glamor_priv->back_pixmap && *glamor_priv->back_pixmap)
glamor_set_pixmap_private(*glamor_priv->back_pixmap, NULL);
glamor_release_screen_priv(screen);
return screen->CloseScreen(idx, screen);

View File

@ -120,7 +120,7 @@ extern _X_EXPORT Bool glamor_close_screen(int idx, ScreenPtr screen);
/* Let glamor to know the screen's fbo. The low level
* driver should already assign a tex
* to this pixmap through the set_pixmap_texture. */
extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap);
extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, PixmapPtr *back_pixmap);
/* @glamor_glyphs_init: Initialize glyphs internal data structures.
*
@ -146,6 +146,16 @@ extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
extern _X_EXPORT void glamor_egl_make_current(ScreenPtr screen);
extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
/* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
*
* @front: front pixmap.
* @back: back pixmap.
*
* Used by the DRI2 page flip. This function will exchange the KHR images and
* fbos of the two pixmaps.
* */
extern _X_EXPORT void glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back);
#ifdef GLAMOR_FOR_XORG
#define GLAMOR_EGL_MODULE_NAME "glamoregl"
@ -183,6 +193,18 @@ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen);
extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
int handle,
int stride);
/* @glamor_egl_create_textured_screen_ext:
*
* extent one parameter to track the pointer of the DDX layer's back pixmap.
* We need this pointer during the closing screen stage. As before back to
* the DDX's close screen, we have to free all the glamor related resources.
*/
extern _X_EXPORT Bool glamor_egl_create_textured_screen_ext(ScreenPtr screen,
int handle,
int stride,
PixmapPtr *back_pixmap);
/*
* @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
* a BO handle.

View File

@ -85,6 +85,7 @@ struct glamor_egl_screen_private {
CloseScreenProcPtr CloseScreen;
int fd;
EGLImageKHR front_image;
PixmapPtr *back_pixmap;
int cpp;
#ifdef GLAMOR_HAS_GBM
struct gbm_device *gbm;
@ -233,7 +234,24 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates,
glamor_egl_pixmap_private_key);
glamor_set_screen_pixmap(screen_pixmap);
glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap);
return TRUE;
}
Bool
glamor_egl_create_textured_screen_ext(ScreenPtr screen,
int handle,
int stride,
PixmapPtr *back_pixmap)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
struct glamor_egl_screen_private *glamor_egl;
glamor_egl = glamor_egl_get_screen_private(scrn);
glamor_egl->back_pixmap = back_pixmap;
if (!glamor_egl_create_textured_screen(screen, handle, stride))
return FALSE;
return TRUE;
}
@ -280,9 +298,10 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
((stride * 8 + 7) / pixmap->drawable.bitsPerPixel),
name,
pixmap->drawable.depth);
if (image == EGL_NO_IMAGE_KHR)
if (image == EGL_NO_IMAGE_KHR) {
glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
goto done;
}
glamor_create_texture_from_image(glamor_egl, image, &texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_texture(pixmap, texture);
@ -315,6 +334,28 @@ _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
}
}
extern void glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back);
_X_EXPORT void
glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back)
{
ScrnInfoPtr scrn = xf86Screens[front->drawable.pScreen->myNum];
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(scrn);
EGLImageKHR old_front_image;
EGLImageKHR new_front_image;
glamor_pixmap_exchange_fbos(front, back);
new_front_image = dixLookupPrivate(&back->devPrivates, glamor_egl_pixmap_private_key);
old_front_image = dixLookupPrivate(&front->devPrivates, glamor_egl_pixmap_private_key);
dixSetPrivate(&front->devPrivates, glamor_egl_pixmap_private_key, new_front_image);
dixSetPrivate(&back->devPrivates, glamor_egl_pixmap_private_key, old_front_image);
glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM);
glamor_egl->front_image = new_front_image;
}
void
glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
{
@ -329,13 +370,24 @@ glamor_egl_close_screen(int idx, ScreenPtr screen)
ScrnInfoPtr scrn;
struct glamor_egl_screen_private *glamor_egl;
PixmapPtr screen_pixmap;
EGLImageKHR back_image;
scrn = xf86Screens[screen->myNum];
glamor_egl = glamor_egl_get_screen_private(scrn);
screen_pixmap = screen->GetScreenPixmap(screen);
glamor_egl->egl_destroy_image_khr(glamor_egl->display, glamor_egl->front_image);
dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL);
glamor_egl->front_image = NULL;
if (glamor_egl->back_pixmap && *glamor_egl->back_pixmap) {
back_image = dixLookupPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
glamor_egl_pixmap_private_key);
if (back_image != NULL && back_image != EGL_NO_IMAGE_KHR) {
glamor_egl->egl_destroy_image_khr(glamor_egl->display, back_image);
dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates,
glamor_egl_pixmap_private_key, NULL);
}
}
screen->CloseScreen = glamor_egl->saved_close_screen;
@ -383,7 +435,6 @@ glamor_egl_free_screen(int scrnIndex, int flags)
ScrnInfoPtr scrn = xf86Screens[scrnIndex];
struct glamor_egl_screen_private *glamor_egl;
ErrorF("free egl screen resources\n");
glamor_egl = glamor_egl_get_screen_private(scrn);
if (glamor_egl != NULL) {

View File

@ -427,3 +427,22 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
break;
}
}
/*
* XXX how to handle those pending OPs.
* By default, pending OP is disabled. Maybe we will give up the pending
* OP latter.
*
* */
_X_EXPORT void
glamor_pixmap_exchange_fbos(PixmapPtr front, PixmapPtr back)
{
glamor_pixmap_private *front_priv, *back_priv;
glamor_pixmap_fbo *temp_fbo;
front_priv = glamor_get_pixmap_private(front);
back_priv = glamor_get_pixmap_private(back);
temp_fbo = front_priv->fbo;
front_priv->fbo = back_priv->fbo;
back_priv->fbo = temp_fbo;
}

View File

@ -212,6 +212,7 @@ typedef struct glamor_screen_private {
GLint put_image_xybitmap_fg_uniform_location;
GLint put_image_xybitmap_bg_uniform_location;
PixmapPtr *back_pixmap;
int screen_fbo;
struct glamor_saved_procs saved_procs;
char delayed_fallback_string[GLAMOR_DELAYED_STRING_MAX + 1];
@ -344,16 +345,7 @@ glamor_get_pixmap_private(PixmapPtr pixmap)
glamor_pixmap_private_key);
}
static inline void
glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv)
{
dixSetPrivate(&pixmap->devPrivates,
glamor_pixmap_private_key,
priv);
}
void glamor_set_pixmap_private(PixmapPtr pixmap, glamor_pixmap_private *priv);
/**
* Returns TRUE if the given planemask covers all the significant bits in the