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:
parent
8012b030c3
commit
213285f2b8
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue