glamor: Delay making pixmaps shareable until we need to.
If a pixmap isn't getting exported as a dmabuf, then we don't need to make an EGLImage/GBM bo for it. This should reduce normal pixmap allocation overhead, and also lets the driver choose non-scanout formats which may be much higher performance. On Raspberry Pi, where scanout isn't usable as a texture source, this improves x11perf -copypixwin100 from about 4300/sec to 5780/sec under xcompmgr -a, because we no longer need to upload our x11perf window to a tiled temporary in order to render it to the screen. v2: Just use pixmap->usage_hint instead of a new field. Drop the changes that started storing gbm_bos in the pixmap priv due to lifetime issues. v3: Fix a missing gbm_bo_destroy() on the pixmap-from-fd success path. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
7cd495a888
commit
51984dddfc
|
@ -140,11 +140,6 @@ extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front,
|
|||
|
||||
/* The DDX is not supposed to call these three functions */
|
||||
extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
|
||||
extern _X_EXPORT unsigned int glamor_egl_create_argb8888_based_texture(ScreenPtr
|
||||
screen,
|
||||
int w,
|
||||
int h,
|
||||
Bool linear);
|
||||
extern _X_EXPORT int glamor_egl_dri3_fd_name_from_tex(ScreenPtr, PixmapPtr,
|
||||
unsigned int, Bool,
|
||||
CARD16 *, CARD32 *);
|
||||
|
|
|
@ -187,49 +187,6 @@ glamor_egl_get_gbm_device(ScreenPtr screen)
|
|||
#endif
|
||||
}
|
||||
|
||||
unsigned int
|
||||
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
|
||||
{
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
struct glamor_egl_screen_private *glamor_egl;
|
||||
EGLImageKHR image;
|
||||
GLuint texture;
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
struct gbm_bo *bo;
|
||||
EGLNativePixmapType native_pixmap;
|
||||
|
||||
glamor_egl = glamor_egl_get_screen_private(scrn);
|
||||
bo = gbm_bo_create(glamor_egl->gbm, w, h, GBM_FORMAT_ARGB8888,
|
||||
#ifdef GLAMOR_HAS_GBM_LINEAR
|
||||
(linear ? GBM_BO_USE_LINEAR : 0) |
|
||||
#endif
|
||||
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
||||
if (!bo)
|
||||
return 0;
|
||||
|
||||
/* If the following assignment raises an error or a warning
|
||||
* then that means EGLNativePixmapType is not struct gbm_bo *
|
||||
* on your platform: This code won't work and you should not
|
||||
* compile with dri3 support enabled */
|
||||
native_pixmap = bo;
|
||||
|
||||
image = eglCreateImageKHR(glamor_egl->display,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_PIXMAP_KHR,
|
||||
native_pixmap, NULL);
|
||||
gbm_bo_destroy(bo);
|
||||
if (image == EGL_NO_IMAGE_KHR)
|
||||
return 0;
|
||||
glamor_create_texture_from_image(screen, image, &texture);
|
||||
eglDestroyImageKHR(glamor_egl->display, image);
|
||||
|
||||
return texture;
|
||||
#else
|
||||
return 0; /* this path should never happen */
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool
|
||||
glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride)
|
||||
{
|
||||
|
@ -380,79 +337,92 @@ glamor_get_name_from_bo(int gbm_fd, struct gbm_bo *bo, int *name)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
static void *
|
||||
_get_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, unsigned int tex)
|
||||
static Bool
|
||||
glamor_make_pixmap_exportable(PixmapPtr pixmap)
|
||||
{
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
struct glamor_egl_screen_private *glamor_egl =
|
||||
glamor_egl_get_screen_private(scrn);
|
||||
struct glamor_pixmap_private *pixmap_priv =
|
||||
glamor_get_pixmap_private(pixmap);
|
||||
struct glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(screen);
|
||||
struct glamor_egl_screen_private *glamor_egl;
|
||||
EGLImageKHR image;
|
||||
unsigned width = pixmap->drawable.width;
|
||||
unsigned height = pixmap->drawable.height;
|
||||
struct gbm_bo *bo;
|
||||
PixmapPtr exported;
|
||||
GCPtr scratch_gc;
|
||||
|
||||
EGLint attribs[] = {
|
||||
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
||||
EGL_GL_TEXTURE_LEVEL_KHR, 0,
|
||||
EGL_NONE
|
||||
};
|
||||
if (pixmap_priv->image)
|
||||
return TRUE;
|
||||
|
||||
glamor_egl = glamor_egl_get_screen_private(scrn);
|
||||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
image = pixmap_priv->image;
|
||||
if (!image) {
|
||||
image = eglCreateImageKHR(glamor_egl->display,
|
||||
glamor_egl->context,
|
||||
EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer) (uintptr_t)
|
||||
tex, attribs);
|
||||
if (image == EGL_NO_IMAGE_KHR)
|
||||
return NULL;
|
||||
|
||||
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
|
||||
glamor_egl_set_pixmap_image(pixmap, image);
|
||||
if (pixmap->drawable.bitsPerPixel != 32) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
||||
"Failed to make %dbpp pixmap exportable\n",
|
||||
pixmap->drawable.bitsPerPixel);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0);
|
||||
if (!bo)
|
||||
return NULL;
|
||||
|
||||
pixmap->devKind = gbm_bo_get_stride(bo);
|
||||
|
||||
return bo;
|
||||
}
|
||||
bo = gbm_bo_create(glamor_egl->gbm, width, height,
|
||||
GBM_FORMAT_ARGB8888,
|
||||
#ifdef GLAMOR_HAS_GBM_LINEAR
|
||||
(pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED ?
|
||||
GBM_BO_USE_LINEAR : 0) |
|
||||
#endif
|
||||
GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
|
||||
if (!bo) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
||||
"Failed to make %dx%dx%dbpp GBM bo\n",
|
||||
width, height, pixmap->drawable.bitsPerPixel);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exported = screen->CreatePixmap(screen, 0, 0, pixmap->drawable.depth, 0);
|
||||
screen->ModifyPixmapHeader(exported, width, height, 0, 0,
|
||||
gbm_bo_get_stride(bo), NULL);
|
||||
if (!glamor_egl_create_textured_pixmap_from_gbm_bo(exported, bo)) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
|
||||
"Failed to make %dx%dx%dbpp pixmap from GBM bo\n",
|
||||
width, height, pixmap->drawable.bitsPerPixel);
|
||||
screen->DestroyPixmap(exported);
|
||||
gbm_bo_destroy(bo);
|
||||
return FALSE;
|
||||
}
|
||||
gbm_bo_destroy(bo);
|
||||
|
||||
scratch_gc = GetScratchGC(pixmap->drawable.depth, screen);
|
||||
ValidateGC(&pixmap->drawable, scratch_gc);
|
||||
scratch_gc->ops->CopyArea(&pixmap->drawable, &exported->drawable,
|
||||
scratch_gc,
|
||||
0, 0, width, height, 0, 0);
|
||||
FreeScratchGC(scratch_gc);
|
||||
|
||||
/* Now, swap the tex/gbm/EGLImage/etc. of the exported pixmap into
|
||||
* the original pixmap struct.
|
||||
*/
|
||||
glamor_egl_exchange_buffers(pixmap, exported);
|
||||
|
||||
screen->DestroyPixmap(exported);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct gbm_bo *
|
||||
glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
|
||||
{
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(pixmap->drawable.pScreen);
|
||||
glamor_pixmap_private *pixmap_priv =
|
||||
struct glamor_egl_screen_private *glamor_egl =
|
||||
glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
||||
struct glamor_pixmap_private *pixmap_priv =
|
||||
glamor_get_pixmap_private(pixmap);
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||
if (!glamor_priv->dri3_enabled)
|
||||
if (!glamor_make_pixmap_exportable(pixmap))
|
||||
return NULL;
|
||||
switch (pixmap_priv->type) {
|
||||
case GLAMOR_TEXTURE_DRM:
|
||||
case GLAMOR_TEXTURE_ONLY:
|
||||
if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
|
||||
return NULL;
|
||||
return _get_gbm_bo_from_pixmap(screen, pixmap,
|
||||
pixmap_priv->fbo->tex);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE,
|
||||
pixmap_priv->image, 0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -468,7 +438,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
|
|||
|
||||
glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
|
||||
|
||||
bo = _get_gbm_bo_from_pixmap(screen, pixmap, tex);
|
||||
bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
|
||||
if (!bo)
|
||||
goto failure;
|
||||
|
||||
|
@ -504,8 +474,8 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
|
|||
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
||||
struct glamor_egl_screen_private *glamor_egl;
|
||||
struct gbm_bo *bo;
|
||||
Bool ret = FALSE;
|
||||
struct gbm_import_fd_data import_data = { 0 };
|
||||
Bool ret;
|
||||
|
||||
glamor_egl = glamor_egl_get_screen_private(scrn);
|
||||
|
||||
|
@ -528,10 +498,7 @@ glamor_back_pixmap_from_fd(PixmapPtr pixmap,
|
|||
|
||||
ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo);
|
||||
gbm_bo_destroy(bo);
|
||||
|
||||
if (ret)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
return ret;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
|
|
|
@ -43,9 +43,3 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -329,30 +329,19 @@ glamor_destroy_fbo(glamor_screen_private *glamor_priv,
|
|||
|
||||
static int
|
||||
_glamor_create_tex(glamor_screen_private *glamor_priv,
|
||||
int w, int h, GLenum format, Bool linear)
|
||||
int w, int h, GLenum format)
|
||||
{
|
||||
unsigned int tex = 0;
|
||||
unsigned int tex;
|
||||
|
||||
/* With dri3, we want to allocate ARGB8888 pixmaps only.
|
||||
* Depending on the implementation, GL_RGBA might not
|
||||
* give us ARGB8888. We ask glamor_egl to use get
|
||||
* an ARGB8888 based texture for us. */
|
||||
if (glamor_priv->dri3_enabled && format == GL_RGBA) {
|
||||
tex = glamor_egl_create_argb8888_based_texture(glamor_priv->screen,
|
||||
w, h, linear);
|
||||
}
|
||||
if (!tex) {
|
||||
glamor_make_current(glamor_priv);
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glamor_priv->suppress_gl_out_of_memory_logging = true;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
|
||||
format, GL_UNSIGNED_BYTE, NULL);
|
||||
glamor_priv->suppress_gl_out_of_memory_logging = false;
|
||||
}
|
||||
glamor_make_current(glamor_priv);
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glamor_priv->suppress_gl_out_of_memory_logging = true;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
|
||||
format, GL_UNSIGNED_BYTE, NULL);
|
||||
glamor_priv->suppress_gl_out_of_memory_logging = false;
|
||||
|
||||
if (glGetError() == GL_OUT_OF_MEMORY) {
|
||||
if (!glamor_priv->logged_any_fbo_allocation_failure) {
|
||||
|
@ -383,7 +372,7 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
|
|||
if (fbo)
|
||||
return fbo;
|
||||
new_fbo:
|
||||
tex = _glamor_create_tex(glamor_priv, w, h, format, flag == CREATE_PIXMAP_USAGE_SHARED);
|
||||
tex = _glamor_create_tex(glamor_priv, w, h, format);
|
||||
if (!tex)
|
||||
return NULL;
|
||||
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, format, tex, flag);
|
||||
|
@ -548,7 +537,7 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
|
|||
if (!pixmap_priv->fbo->tex)
|
||||
pixmap_priv->fbo->tex =
|
||||
_glamor_create_tex(glamor_priv, pixmap->drawable.width,
|
||||
pixmap->drawable.height, format, FALSE);
|
||||
pixmap->drawable.height, format);
|
||||
|
||||
if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->fbo->fb == 0)
|
||||
if (glamor_pixmap_ensure_fb(glamor_priv, pixmap_priv->fbo) != 0)
|
||||
|
|
|
@ -409,12 +409,6 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h, Bool linear)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct xwl_auth_state {
|
||||
int fd;
|
||||
ClientPtr client;
|
||||
|
|
Loading…
Reference in New Issue
Block a user