diff --git a/glamor/glamor.c b/glamor/glamor.c index 80434e959..e900a911b 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -318,6 +318,13 @@ glamor_init(ScreenPtr screen, unsigned int flags) #else glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP; #endif + /* If we are using egl screen, call egl screen init to + * register correct close screen function. */ + if (flags & GLAMOR_USE_EGL_SCREEN) + glamor_egl_screen_init(screen); + + glamor_priv->saved_procs.close_screen = screen->CloseScreen; + screen->CloseScreen = glamor_close_screen; if (flags & GLAMOR_USE_SCREEN) { if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler, @@ -327,9 +334,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) goto fail; } - glamor_priv->saved_procs.close_screen = screen->CloseScreen; - screen->CloseScreen = glamor_close_screen; - glamor_priv->saved_procs.create_gc = screen->CreateGC; screen->CreateGC = glamor_create_gc; @@ -427,6 +431,9 @@ Bool glamor_close_screen(int idx, ScreenPtr screen) { glamor_screen_private *glamor_priv; + PixmapPtr screen_pixmap; + glamor_pixmap_private *screen_pixmap_priv; + glamor_pixmap_fbo *fbo; int flags; glamor_priv = glamor_get_screen_private(screen); @@ -435,9 +442,9 @@ glamor_close_screen(int idx, ScreenPtr screen) PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif glamor_glyphs_fini(screen); + screen->CloseScreen = glamor_priv->saved_procs.close_screen; if (flags & GLAMOR_USE_SCREEN) { - screen->CloseScreen = glamor_priv->saved_procs.close_screen; screen->CreateGC = glamor_priv->saved_procs.create_gc; screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap; screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap; @@ -457,12 +464,13 @@ glamor_close_screen(int idx, ScreenPtr screen) ps->CreatePicture = glamor_priv->saved_procs.create_picture; } #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_release_screen_priv(screen); - if (flags & GLAMOR_USE_SCREEN) - return screen->CloseScreen(idx, screen); - else - return TRUE; + return screen->CloseScreen(idx, screen); } diff --git a/glamor/glamor.h b/glamor/glamor.h index fe1570022..e29a3e43f 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -41,36 +41,6 @@ #endif /* GLAMOR_H */ -/* @GLAMOR_INVERTED_Y_AXIS: - * set 1 means the GL env's origin (0,0) is at top-left. - * EGL/DRM platform is an example need to set this bit. - * glx platform's origin is at bottom-left thus need to - * clear this bit.*/ - -#define GLAMOR_INVERTED_Y_AXIS 1 - -/* @GLAMOR_USE_SCREEN: - * If want to let glamor to do everything including the - * create/destroy pixmap and handle the gc ops. need to - * set this bit. Standalone glamor DDX driver need to set - * this bit. - * Otherwise, need to clear this bit, as the intel video - * driver with glamor enabled. - * */ -#define GLAMOR_USE_SCREEN 2 -/* @GLAMOR_USE_PICTURE_SCREEN: - * If want to let glamor to do all the composition related - * things, need to set this bit. Just as standalone glamor - * DDX driver. - * Otherwise, need to clear this bit, as the intel video - * driver with glamor enabled. - */ -#define GLAMOR_USE_PICTURE_SCREEN 4 - -#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \ - | GLAMOR_USE_SCREEN \ - | GLAMOR_USE_PICTURE_SCREEN) - /* * glamor_pixmap_type : glamor pixmap's type. * @MEMORY: pixmap is in memory. @@ -90,15 +60,49 @@ typedef enum glamor_pixmap_type { } glamor_pixmap_type_t; #define GLAMOR_EGL_EXTERNAL_BUFFER 3 +#define GLAMOR_INVERTED_Y_AXIS 1 +#define GLAMOR_USE_SCREEN (1 << 1) +#define GLAMOR_USE_PICTURE_SCREEN (1 << 2) +#define GLAMOR_USE_EGL_SCREEN (1 << 3) +#define GLAMOR_VALID_FLAGS (GLAMOR_INVERTED_Y_AXIS \ + | GLAMOR_USE_SCREEN \ + | GLAMOR_USE_PICTURE_SCREEN \ + | GLAMOR_USE_EGL_SCREEN) + /* @glamor_init: Initialize glamor internal data structure. * * @screen: Current screen pointer. * @flags: Please refer the flags description above. * + * @GLAMOR_INVERTED_Y_AXIS: + * set 1 means the GL env's origin (0,0) is at top-left. + * EGL/DRM platform is an example need to set this bit. + * glx platform's origin is at bottom-left thus need to + * clear this bit. + * + * @GLAMOR_USE_SCREEN: + * If running in an pre-existing X environment, and the + * gl context is GLX, then you should set this bit and + * let the glamor to handle all the screen related + * functions such as GC ops and CreatePixmap/DestroyPixmap. + * + * @GLAMOR_USE_PICTURE_SCREEN: + * If don't use any other underlying DDX driver to handle + * the picture related rendering functions, please set this + * bit on. Otherwise, clear this bit. And then it is the DDX + * driver's responsibility to determine how/when to jump to + * glamor's picture compositing path. + * + * @GLAMOR_USE_EGL_SCREEN: + * If you are using EGL layer, then please set this bit + * on, otherwise, clear it. + * * This function initializes necessary internal data structure * for glamor. And before calling into this function, the OpenGL * environment should be ready. Should be called before any real - * glamor rendering or texture allocation functions. + * glamor rendering or texture allocation functions. And should + * be called after the DDX's screen initialization or at the last + * step of the DDX's screen initialization. */ extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags); extern _X_EXPORT void glamor_fini(ScreenPtr screen); @@ -139,6 +143,8 @@ extern _X_EXPORT void glamor_block_handler(ScreenPtr screen); extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned int usage); +extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen); + #ifdef GLAMOR_FOR_XORG /* @glamor_egl_init: Initialize EGL environment. * @@ -173,7 +179,6 @@ 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_pixmap: Try to create a textured pixmap from * a BO handle. @@ -191,10 +196,6 @@ extern _X_EXPORT Bool glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int stride); extern _X_EXPORT void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap); - -extern _X_EXPORT Bool glamor_egl_close_screen(ScreenPtr screen); -extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags); - #endif extern _X_EXPORT int glamor_create_gc(GCPtr gc); diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 71121bce7..027722e23 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -84,7 +84,7 @@ struct glamor_egl_screen_private { CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; int fd; - int front_buffer_handle; + EGLImageKHR front_image; int cpp; #ifdef GLAMOR_HAS_GBM struct gbm_device *gbm; @@ -95,6 +95,8 @@ struct glamor_egl_screen_private { PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC egl_image_target_texture2d_oes; struct glamor_gl_dispatch *dispatch; + CloseScreenProcPtr saved_close_screen; + xf86FreeScreenProc *saved_free_screen; }; int xf86GlamorEGLPrivateIndex = -1; @@ -185,6 +187,8 @@ glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride) return FALSE; } + glamor_egl->front_image = dixLookupPrivate(&screen_pixmap->devPrivates, + glamor_egl_pixmap_private_key); glamor_set_screen_pixmap(screen_pixmap); return TRUE; } @@ -242,37 +246,51 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) return TRUE; } +static void +_glamor_egl_destroy_pixmap_image(PixmapPtr pixmap) +{ + ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; + EGLImageKHR image; + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + + image = dixLookupPrivate(&pixmap->devPrivates, + glamor_egl_pixmap_private_key); + if (image != EGL_NO_IMAGE_KHR && image != NULL) { + /* Before destroy an image which was attached to + * a texture. we must call glFlush to make sure the + * operation on that texture has been done.*/ + glamor_block_handler(pixmap->drawable.pScreen); + glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); + dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, NULL); + } +} + void glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap) { - EGLImageKHR image; - ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - - if (pixmap->refcnt == 1) { - image = dixLookupPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key); - if (image != EGL_NO_IMAGE_KHR && image != NULL) { - /* Before destroy an image which was attached to - * a texture. we must call glFlush to make sure the - * operation on that texture has been done.*/ - glamor_block_handler(pixmap->drawable.pScreen); - glamor_egl->egl_destroy_image_khr(glamor_egl->display, image); - } - } + if (pixmap->refcnt == 1) + _glamor_egl_destroy_pixmap_image(pixmap); glamor_destroy_textured_pixmap(pixmap); } -Bool -glamor_egl_close_screen(ScreenPtr screen) +static Bool +glamor_egl_close_screen(int idx, ScreenPtr screen) { - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - glamor_fini(screen); + ScrnInfoPtr scrn; + struct glamor_egl_screen_private *glamor_egl; + PixmapPtr screen_pixmap; - return TRUE; + 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; + + screen->CloseScreen = glamor_egl->saved_close_screen; + + return screen->CloseScreen(idx, screen); } static Bool @@ -299,6 +317,40 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, return FALSE; } +void +glamor_egl_screen_init(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + struct glamor_egl_screen_private *glamor_egl = + glamor_egl_get_screen_private(scrn); + + glamor_egl->saved_close_screen = screen->CloseScreen; + screen->CloseScreen = glamor_egl_close_screen; +} + +static void +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) { + + eglMakeCurrent(glamor_egl->display, + EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); +#ifdef GLAMOR_HAS_GBM + if (glamor_egl->gbm) + gbm_device_destroy(glamor_egl->gbm); +#endif + scrn->FreeScreen = glamor_egl->saved_free_screen; + free(glamor_egl); + scrn->FreeScreen(scrnIndex, flags); + } +} + Bool glamor_egl_init(ScrnInfoPtr scrn, int fd) { @@ -396,6 +448,8 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) return FALSE; } + glamor_egl->saved_free_screen = scrn->FreeScreen; + scrn->FreeScreen = glamor_egl_free_screen; return TRUE; } @@ -412,27 +466,6 @@ glamor_egl_init_textured_pixmap(ScreenPtr screen) return TRUE; } -void -glamor_egl_free_screen(int scrnIndex, int flags) -{ - ScrnInfoPtr scrn = xf86Screens[scrnIndex]; - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - - if (glamor_egl != NULL) { - if (!(flags & GLAMOR_EGL_EXTERNAL_BUFFER)) { - eglMakeCurrent(glamor_egl->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - - eglTerminate(glamor_egl->display); - } - free(glamor_egl); - } - - glamor_close_screen(scrn->scrnIndex, scrn->pScreen); -} - Bool glamor_gl_dispatch_init(ScreenPtr screen, struct glamor_gl_dispatch *dispatch, diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index ffda04ae0..2243564f6 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -123,7 +123,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv, return NULL; } -static void +void glamor_purge_fbo(glamor_pixmap_fbo *fbo) { glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 9c2881cbd..d8168a52f 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -346,6 +346,7 @@ glamor_pixmap_fbo * glamor_create_fbo_from_tex(glamor_screen_private *glamor_pri glamor_pixmap_fbo * glamor_create_fbo(glamor_screen_private *glamor_priv, int w, int h, int depth, int flag); void glamor_destroy_fbo(glamor_pixmap_fbo *fbo); +void glamor_purge_fbo(glamor_pixmap_fbo *fbo); void glamor_init_pixmap_fbo(ScreenPtr screen); void glamor_fini_pixmap_fbo(ScreenPtr screen);