From f31911ff8f3f3707101b7771d5dc994ed1ca5c70 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Feb 2014 17:55:50 -0800 Subject: [PATCH 01/33] xephyr: Don't forget to glViewport() before drawing the screen. Fixes misrendering with cairogears. I had noticed the failure while trying to figure out what was going on with traps. Cairogears was apparently putting its results on the screen through putimage, which is a texture upload, so the last GL drawing was done to the size of the cairogears window, not the size of the xephyr screen. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- hw/kdrive/ephyr/ephyr_glamor_glx.c | 15 +++++++++++++++ hw/kdrive/ephyr/ephyr_glamor_glx.h | 10 ++++++++++ hw/kdrive/ephyr/hostx.c | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c index d56907fe7..eaf565496 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -67,6 +67,9 @@ struct ephyr_glamor { GLuint texture_shader; GLuint texture_shader_position_loc; GLuint texture_shader_texcoord_loc; + + /* Size of the window that we're rendering to. */ + unsigned width, height; }; static GLint @@ -205,6 +208,7 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(glamor->texture_shader); + glViewport(0, 0, glamor->width, glamor->height); glVertexAttribPointer(glamor->texture_shader_position_loc, 2, GL_FLOAT, FALSE, 0, position); @@ -329,3 +333,14 @@ ephyr_glamor_get_visual(void) return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid); } + +void +ephyr_glamor_set_window_size(struct ephyr_glamor *glamor, + unsigned width, unsigned height) +{ + if (!glamor) + return; + + glamor->width = width; + glamor->height = height; +} diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.h b/hw/kdrive/ephyr/ephyr_glamor_glx.h index 8995e1eca..0c238cf5b 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.h +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.h @@ -50,6 +50,10 @@ void ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor); #ifdef GLAMOR +void +ephyr_glamor_set_window_size(struct ephyr_glamor *glamor, + unsigned width, unsigned height); + void ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, struct pixman_region16 *damage); @@ -59,6 +63,12 @@ ephyr_glamor_process_event(xcb_generic_event_t *xev); #else /* !GLAMOR */ +static inline void +ephyr_glamor_set_window_size(struct ephyr_glamor *glamor, + unsigned width, unsigned height) +{ +} + static inline void ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor, struct pixman_region16 *damage) diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 859becaa6..0a9eb4696 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -731,6 +731,8 @@ hostx_screen_init(KdScreenInfo *screen, if (ephyr_glamor) { *bytes_per_line = 0; *bits_per_pixel = 0; + ephyr_glamor_set_window_size(scrpriv->glamor, + scrpriv->win_width, scrpriv->win_height); return NULL; } else if (host_depth_matches_server(scrpriv)) { *bytes_per_line = scrpriv->ximg->stride; @@ -1218,6 +1220,8 @@ ephyr_glamor_init(ScreenPtr screen) EphyrScrPriv *scrpriv = kd_screen->driver; scrpriv->glamor = ephyr_glamor_glx_screen_init(scrpriv->win); + ephyr_glamor_set_window_size(scrpriv->glamor, + scrpriv->win_width, scrpriv->win_height); glamor_init(screen, GLAMOR_USE_SCREEN | From a895f6a16588024e03218d8d0e77dd8bd8494329 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 5 Jan 2014 02:45:05 -0800 Subject: [PATCH 02/33] glamor: Drop the set of the context to NULL at the end of glamor ops. The theory here was that it (which I copied from EGL) existed to fix up context switching with indirect GLX. But indirect GLX won't even try to set the context again unless its lastContext field is cleared, so we need to solve this a different way. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_glx.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/glamor/glamor_glx.c b/glamor/glamor_glx.c index 311bf758d..8f47c3d2c 100644 --- a/glamor/glamor_glx.c +++ b/glamor/glamor_glx.c @@ -53,13 +53,7 @@ glamor_glx_get_context(struct glamor_context *glamor_ctx) static void glamor_glx_put_context(struct glamor_context *glamor_ctx) { - if (--glamor_ctx->get_count) - return; - - /* We actually reset the context, so that indirect GLX's EGL usage - * won't get confused by ours. - */ - glXMakeCurrent(glamor_ctx->display, None, NULL); + --glamor_ctx->get_count; } Bool From 732faea542c5ecab353536f93bab5dc6c6068d0a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Dec 2013 18:27:56 -0800 Subject: [PATCH 03/33] glamor: Use epoxy_has_egl_extension() instead of rolling our own. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_egl.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 05e6bd02e..13799fc71 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -610,25 +610,6 @@ glamor_egl_close_screen(ScreenPtr screen) return screen->CloseScreen(screen); } -static Bool -glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl, - const char *extension) -{ - const char *pext; - int ext_len; - - ext_len = strlen(extension); - pext = (const char *) eglQueryString(glamor_egl->display, EGL_EXTENSIONS); - if (pext == NULL || extension == NULL) - return FALSE; - while ((pext = strstr(pext, extension)) != NULL) { - if (pext[ext_len] == ' ' || pext[ext_len] == '\0') - return TRUE; - pext += ext_len; - } - return FALSE; -} - static int glamor_dri3_open(ScreenPtr screen, RRProviderPtr provider, @@ -799,14 +780,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) xf86Msg(X_INFO, "%s: EGL version %s:\n", glamor_name, version); #define GLAMOR_CHECK_EGL_EXTENSION(EXT) \ - if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT)) { \ + if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT)) { \ ErrorF("EGL_" #EXT " required.\n"); \ return FALSE; \ } #define GLAMOR_CHECK_EGL_EXTENSIONS(EXT1, EXT2) \ - if (!glamor_egl_has_extension(glamor_egl, "EGL_" #EXT1) && \ - !glamor_egl_has_extension(glamor_egl, "EGL_" #EXT2)) { \ + if (!epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT1) && \ + !epoxy_has_egl_extension(glamor_egl->display, "EGL_" #EXT2)) { \ ErrorF("EGL_" #EXT1 " or EGL_" #EXT2 " required.\n"); \ return FALSE; \ } @@ -821,8 +802,10 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) #endif #ifdef GLAMOR_HAS_GBM - if (glamor_egl_has_extension(glamor_egl, "EGL_KHR_gl_texture_2D_image") && - glamor_egl_has_extension(glamor_egl, "EGL_EXT_image_dma_buf_import")) + if (epoxy_has_egl_extension(glamor_egl->display, + "EGL_KHR_gl_texture_2D_image") && + epoxy_has_egl_extension(glamor_egl->display, + "EGL_EXT_image_dma_buf_import")) glamor_egl->dri3_capable = TRUE; #endif From df1ef90fa0f98c779c3f312130183dbf32f1e447 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Dec 2013 18:45:44 -0800 Subject: [PATCH 04/33] glamor: Move the EGL image to the normal pixmap private. There's no reason to hide EGL from the rest of glamor, now that we have epoxy. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_egl.c | 89 ++++++++++++++++++++------------------------ glamor/glamor_priv.h | 7 ++++ 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 13799fc71..f24cb28a5 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -54,10 +54,6 @@ static const char glamor_name[] = "glamor"; -static DevPrivateKeyRec glamor_egl_pixmap_private_key_index; -DevPrivateKey glamor_egl_pixmap_private_key = - &glamor_egl_pixmap_private_key_index; - static void glamor_identify(int flags) { @@ -228,11 +224,13 @@ Bool glamor_egl_create_textured_screen(ScreenPtr screen, int handle, int stride) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + struct glamor_pixmap_private *pixmap_priv; struct glamor_egl_screen_private *glamor_egl; PixmapPtr screen_pixmap; glamor_egl = glamor_egl_get_screen_private(scrn); screen_pixmap = screen->GetScreenPixmap(screen); + pixmap_priv = glamor_get_pixmap_private(screen_pixmap); if (!glamor_egl_create_textured_pixmap(screen_pixmap, handle, stride)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, @@ -240,8 +238,7 @@ 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_egl->front_image = pixmap_priv->base.image; glamor_set_screen_pixmap(screen_pixmap, glamor_egl->back_pixmap); return TRUE; } @@ -282,6 +279,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + struct glamor_pixmap_private *pixmap_priv = + glamor_get_pixmap_private(pixmap); struct glamor_egl_screen_private *glamor_egl; EGLImageKHR image; GLuint texture; @@ -316,7 +315,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride) glamor_create_texture_from_image(glamor_egl, image, &texture); glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_texture(pixmap, texture); - dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image); + pixmap_priv->base.image = image; ret = TRUE; done: @@ -331,6 +330,8 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + struct glamor_pixmap_private *pixmap_priv = + glamor_get_pixmap_private(pixmap); struct glamor_egl_screen_private *glamor_egl; EGLImageKHR image; GLuint texture; @@ -350,7 +351,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo) glamor_create_texture_from_image(glamor_egl, image, &texture); glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_texture(pixmap, texture); - dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image); + pixmap_priv->base.image = image; ret = TRUE; done: @@ -395,6 +396,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, { #ifdef GLAMOR_HAS_GBM ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + 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; @@ -412,10 +415,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, glamor_get_context(glamor_priv); - image = dixLookupPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key); - - if (image == EGL_NO_IMAGE_KHR || image == NULL) { + image = pixmap_priv->base.image; + if (!image) { image = eglCreateImageKHR(glamor_egl->display, glamor_egl->context, EGL_GL_TEXTURE_2D_KHR, @@ -424,8 +425,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, if (image == EGL_NO_IMAGE_KHR) goto failure; - dixSetPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key, image); + pixmap_priv->base.image = image; glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); } @@ -530,20 +530,18 @@ static void _glamor_egl_destroy_pixmap_image(PixmapPtr pixmap) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); - EGLImageKHR image; struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); + struct glamor_pixmap_private *pixmap_priv = + glamor_get_pixmap_private(pixmap); - image = dixLookupPrivate(&pixmap->devPrivates, - glamor_egl_pixmap_private_key); - if (image != EGL_NO_IMAGE_KHR && image != NULL) { + if (pixmap_priv->base.image) { /* 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); - eglDestroyImageKHR(glamor_egl->display, image); - dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, - NULL); + eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image); + pixmap_priv->base.image = NULL; } } @@ -553,21 +551,21 @@ glamor_egl_exchange_buffers(PixmapPtr front, PixmapPtr back) ScrnInfoPtr scrn = xf86ScreenToScrn(front->drawable.pScreen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); - EGLImageKHR old_front_image; - EGLImageKHR new_front_image; + EGLImageKHR temp; + struct glamor_pixmap_private *front_priv = + glamor_get_pixmap_private(front); + struct glamor_pixmap_private *back_priv = + glamor_get_pixmap_private(back); 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); + + temp = back_priv->base.image; + back_priv->base.image = front_priv->base.image; + front_priv->base.image = temp; + glamor_set_pixmap_type(front, GLAMOR_TEXTURE_DRM); glamor_set_pixmap_type(back, GLAMOR_TEXTURE_DRM); - glamor_egl->front_image = new_front_image; + glamor_egl->front_image = front_priv->base.image; } @@ -584,24 +582,23 @@ glamor_egl_close_screen(ScreenPtr screen) { ScrnInfoPtr scrn; struct glamor_egl_screen_private *glamor_egl; + struct glamor_pixmap_private *pixmap_priv; PixmapPtr screen_pixmap; - EGLImageKHR back_image; scrn = xf86ScreenToScrn(screen); glamor_egl = glamor_egl_get_screen_private(scrn); screen_pixmap = screen->GetScreenPixmap(screen); + pixmap_priv = glamor_get_pixmap_private(screen_pixmap); - eglDestroyImageKHR(glamor_egl->display,glamor_egl->front_image); - dixSetPrivate(&screen_pixmap->devPrivates, glamor_egl_pixmap_private_key, - NULL); + eglDestroyImageKHR(glamor_egl->display, glamor_egl->front_image); + pixmap_priv->base.image = 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) { - eglDestroyImageKHR(glamor_egl->display, back_image); - dixSetPrivate(&(*glamor_egl->back_pixmap)->devPrivates, - glamor_egl_pixmap_private_key, NULL); + pixmap_priv = glamor_get_pixmap_private(*glamor_egl->back_pixmap); + if (pixmap_priv->base.image) { + eglDestroyImageKHR(glamor_egl->display, pixmap_priv->base.image); + pixmap_priv->base.image = NULL; } } @@ -840,13 +837,7 @@ glamor_egl_init_textured_pixmap(ScreenPtr screen) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); - if (!dixRegisterPrivateKey - (glamor_egl_pixmap_private_key, PRIVATE_PIXMAP, 0)) { - LogMessage(X_WARNING, - "glamor%d: Failed to allocate egl pixmap private\n", - screen->myNum); - return FALSE; - } + if (glamor_egl->dri3_capable) glamor_enable_dri3(screen); return TRUE; diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index d15eabd9e..122f4fd6e 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -36,6 +36,10 @@ #include "glamor.h" #include +#if GLAMOR_HAS_GBM +#define MESA_EGL_NO_X11_HEADERS +#include +#endif #define GLAMOR_DEFAULT_PRECISION \ "#ifdef GL_ES\n" \ @@ -406,6 +410,9 @@ typedef struct glamor_pixmap_private_base { int drm_stride; glamor_screen_private *glamor_priv; PicturePtr picture; +#if GLAMOR_HAS_GBM + EGLImageKHR image; +#endif } glamor_pixmap_private_base_t; /* From 12b2adaaeb091ad48825f439fa0359e5641c86d1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 28 Dec 2013 13:46:17 -0800 Subject: [PATCH 05/33] glamor: Do glyph private init at screeninit time, and other stuff at CSR. This hasn't actually been a problem, since the server hasn't allocated any glyphs before our glyph private initialization during CreateScreenResources. But it's generally not X Server style to do things this way. Now that glamor itself drives both parts of glyphs setup, DDX drivers no longer need to tell glamor to initialize glyphs. We do retain the old public symbol so they can keep running with no changes. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor.c | 30 ++++++++++++++++++++++++++++++ glamor/glamor.h | 8 -------- glamor/glamor_glyphs.c | 21 ++++++++++++++------- glamor/glamor_priv.h | 2 ++ hw/kdrive/ephyr/hostx.c | 3 --- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index e85617927..e298b04cb 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -271,6 +271,29 @@ glamor_set_debug_level(int *debug_level) int glamor_debug_level; +/** + * Creates any pixmaps used internally by glamor, since those can't be + * allocated at ScreenInit time. + */ +static Bool +glamor_create_screen_resources(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + Bool ret = TRUE; + + screen->CreateScreenResources = + glamor_priv->saved_procs.create_screen_resources; + if (screen->CreateScreenResources) + ret = screen->CreateScreenResources(screen); + screen->CreateScreenResources = glamor_create_screen_resources; + + if (!glamor_realize_glyph_caches(screen)) { + ErrorF("Failed to initialize glyph cache\n"); + ret = FALSE; + } + + return ret; +} /** Set up glamor for an already-configured GL context. */ Bool @@ -374,6 +397,10 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->saved_procs.close_screen = screen->CloseScreen; screen->CloseScreen = glamor_close_screen; + glamor_priv->saved_procs.create_screen_resources = + screen->CreateScreenResources; + screen->CreateScreenResources = glamor_create_screen_resources; + if (flags & GLAMOR_USE_SCREEN) { if (!RegisterBlockAndWakeupHandlers(_glamor_block_handler, _glamor_wakeup_handler, @@ -457,6 +484,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_init_xv_shader(screen); #endif glamor_pixmap_init(screen); + glamor_glyphs_init(screen); glamor_priv->flags = flags; glamor_priv->screen = screen; @@ -535,6 +563,8 @@ glamor_close_screen(ScreenPtr screen) flags = glamor_priv->flags; glamor_glyphs_fini(screen); screen->CloseScreen = glamor_priv->saved_procs.close_screen; + screen->CreateScreenResources = + glamor_priv->saved_procs.create_screen_resources; if (flags & GLAMOR_USE_SCREEN) { screen->CreateGC = glamor_priv->saved_procs.create_gc; diff --git a/glamor/glamor.h b/glamor/glamor.h index e25dc735c..9cda46d2b 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -131,14 +131,6 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap); -/* @glamor_glyphs_init: Initialize glyphs internal data structures. - * - * @pScreen: Current screen pointer. - * - * This function must be called after the glamor_init and the texture - * can be allocated. An example is to call it when create the screen - * resources at DDX layer. - */ extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen); extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c index caafa4348..2b2c735d4 100644 --- a/glamor/glamor_glyphs.c +++ b/glamor/glamor_glyphs.c @@ -303,7 +303,7 @@ glamor_glyphs_fini(ScreenPtr pScreen) * rest of the allocated structures for all caches with the given format. */ -static Bool +Bool glamor_realize_glyph_caches(ScreenPtr pScreen) { glamor_screen_private *glamor = glamor_get_screen_private(pScreen); @@ -314,10 +314,6 @@ glamor_realize_glyph_caches(ScreenPtr pScreen) }; int i; - if (glamor->glyph_cache_initialized) - return TRUE; - - glamor->glyph_cache_initialized = TRUE; memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches)); for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) { @@ -370,16 +366,27 @@ glamor_realize_glyph_caches(ScreenPtr pScreen) return FALSE; } +/** + * Called by glamor_create_screen_resources() to set up the glyph cache. + * + * This was previously required to be called by the drivers, but not + * as of the xserver 1.16 ABI. + */ Bool glamor_glyphs_init(ScreenPtr pScreen) { + glamor_screen_private *glamor = glamor_get_screen_private(pScreen); + + if (glamor->glyph_cache_initialized) + return TRUE; + if (!dixRegisterPrivateKey(&glamor_glyph_key, PRIVATE_GLYPH, sizeof(struct glamor_glyph))) return FALSE; - /* Skip pixmap creation if we don't intend to use it. */ + glamor->glyph_cache_initialized = TRUE; - return glamor_realize_glyph_caches(pScreen); + return TRUE; } /* The most efficient thing to way to upload the glyph to the screen diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 122f4fd6e..4dc2c7561 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -173,6 +173,7 @@ typedef struct { struct glamor_saved_procs { CloseScreenProcPtr close_screen; + CreateScreenResourcesProcPtr create_screen_resources; CreateGCProcPtr create_gc; CreatePixmapProcPtr create_pixmap; DestroyPixmapProcPtr destroy_pixmap; @@ -634,6 +635,7 @@ void glamor_get_spans(DrawablePtr drawable, int nspans, char *dst_start); /* glamor_glyphs.c */ +Bool glamor_realize_glyph_caches(ScreenPtr screen); void glamor_glyphs_fini(ScreenPtr screen); void glamor_glyphs(CARD8 op, PicturePtr pSrc, diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 0a9eb4696..3260d9527 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -1243,9 +1243,6 @@ ephyr_glamor_create_screen_resources(ScreenPtr pScreen) if (!ephyr_glamor) return TRUE; - if (!glamor_glyphs_init(pScreen)) - return FALSE; - /* kdrive's fbSetupScreen() told mi to have * miCreateScreenResources() (which is called before this) make a * scratch pixmap wrapping ephyr-glamor's NULL From 92e2125c5219c7b270785f063fe2560583b2baff Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 30 Dec 2013 18:29:50 -0800 Subject: [PATCH 06/33] sync: Add a header include necessary to use misyncstr.h Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- miext/sync/misyncstr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h index b5bf6fd91..ad69e8eca 100644 --- a/miext/sync/misyncstr.h +++ b/miext/sync/misyncstr.h @@ -29,6 +29,7 @@ #define _MISYNCSTR_H_ #include "dix.h" +#include "misync.h" #include "scrnintstr.h" #include From 4e21b7ee49bc8f33c6211411d80aa70b16998adc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 30 Dec 2013 18:33:09 -0800 Subject: [PATCH 07/33] glamor: Drop the body of the function for enabling DRI3 extensions. The flag is already being set at glamor_egl_screen_init() time, so no need for the driver to separately call this. That said, leave the function around to keep the ABI compatibility. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor.h | 8 -------- glamor/glamor_egl.c | 7 +------ 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/glamor/glamor.h b/glamor/glamor.h index 9cda46d2b..be46a5251 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -247,14 +247,6 @@ extern _X_EXPORT PixmapPtr glamor_pixmap_from_fd(ScreenPtr screen, * */ extern _X_EXPORT Bool glamor_egl_init(ScrnInfoPtr scrn, int fd); -/* @glamor_egl_init_textured_pixmap: Initialization for textured pixmap allocation. - * - * @screen: Current screen pointer. - * - * This function must be called before any textured pixmap's creation including - * the screen pixmap. Could be called from DDX's screenInit function after the calling - * to glamor_init.. - */ extern _X_EXPORT Bool glamor_egl_init_textured_pixmap(ScreenPtr screen); /* @glamor_egl_create_textured_screen: Create textured screen pixmap. diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index f24cb28a5..f3835afa2 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -831,14 +831,9 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd) return TRUE; } +/** Stub to retain compatibility with pre-server-1.16 ABI. */ Bool glamor_egl_init_textured_pixmap(ScreenPtr screen) { - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - struct glamor_egl_screen_private *glamor_egl = - glamor_egl_get_screen_private(scrn); - - if (glamor_egl->dri3_capable) - glamor_enable_dri3(screen); return TRUE; } From e23dd41195dfaf1f3e303197845a071d01523618 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 30 Dec 2013 18:41:57 -0800 Subject: [PATCH 08/33] glamor: Return the stride/size for glamor_dri3_name_from_pixmap(), too. Just like for a caller of glamor_dri3_fd_from_pixmap(), otherwise the consumer of that named buffer has no idea what GL chose for the stride. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor.c | 4 ++-- glamor/glamor.h | 3 ++- glamor/glamor_egl.c | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index e298b04cb..5338d45b4 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -647,7 +647,7 @@ glamor_fd_from_pixmap(ScreenPtr screen, } int -glamor_name_from_pixmap(PixmapPtr pixmap) +glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { glamor_pixmap_private *pixmap_priv; glamor_screen_private *glamor_priv = @@ -663,7 +663,7 @@ glamor_name_from_pixmap(PixmapPtr pixmap) return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen, pixmap, pixmap_priv->base.fbo->tex, - TRUE, NULL, NULL); + TRUE, stride, size); default: break; } diff --git a/glamor/glamor.h b/glamor/glamor.h index be46a5251..d05d2f4ea 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -210,7 +210,8 @@ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen, * * Returns the name on success, -1 on error. * */ -extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap); +extern _X_EXPORT int glamor_name_from_pixmap(PixmapPtr pixmap, + CARD16 *stride, CARD32 *size); /* @glamor_pixmap_from_fd: Creates a pixmap to wrap a dma-buf fd. * diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index f3835afa2..812342129 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -441,10 +441,10 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, } else { if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) { - *stride = pixmap->devKind; - *size = pixmap->devKind * gbm_bo_get_height(bo); } } + *stride = pixmap->devKind; + *size = pixmap->devKind * gbm_bo_get_height(bo); gbm_bo_destroy(bo); failure: From d036d22a95b8516a817dd4fa4dd35be363709636 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 4 Jan 2014 13:28:52 -0800 Subject: [PATCH 09/33] glamor: Drop duplicated lines for getting pixmap state in GetImage. No change in generated code size -- apparently the compiler figured it out. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_getimage.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c index 5609e707f..a932473e8 100644 --- a/glamor/glamor_getimage.c +++ b/glamor/glamor_getimage.c @@ -44,8 +44,6 @@ _glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, if (format != ZPixmap) goto fall_back; - pixmap = glamor_get_drawable_pixmap(drawable); - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); if (!glamor_set_planemask(pixmap, planeMask)) { glamor_fallback("Failedto set planemask in glamor_solid.\n"); From ad3dd80720676dcdc11ab5db63ccbed7c9509d7e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Jan 2014 06:52:32 +0800 Subject: [PATCH 10/33] glamor: Fix stack overflow in glamor_solid vertex handling. ARRAY_SIZE(vertices) is 32 (floating point values), so we need to divide by the number of floats in a box like we do in the overflow case below. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_fill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index dda55eace..75c952ca1 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -189,7 +189,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) GLfloat xscale, yscale; float vertices[32]; float *pvertices = vertices; - int valid_nbox = ARRAY_SIZE(vertices); + int valid_nbox = ARRAY_SIZE(vertices) / (4 * 2); glamor_set_destination_pixmap_priv_nc(pixmap_priv); From 20bcda977755559294c3a951f80af2ec861595fc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Jan 2014 06:53:46 +0800 Subject: [PATCH 11/33] glamor: Drop bogus _X_UNLIKELY. nbox > 4 is actually quite common for spans handling. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_fill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 75c952ca1..aaa778300 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -200,7 +200,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - if (_X_UNLIKELY(nbox * 4 * 2 > ARRAY_SIZE(vertices))) { + if (nbox * 4 * 2 > ARRAY_SIZE(vertices)) { int allocated_box; if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) { From 01e30d2043f5df104947908f14a377dc77896a98 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Jan 2014 06:55:15 +0800 Subject: [PATCH 12/33] glamor: Fix some integer overflow errors. Imagine a nbox that was (UINT_MAX + small number) / (4 * 2 * sizeof(float)). We'd malloc a few bytes after the integer overflow, but glamor_set_normalize_vcoords would write over gigabytes of heap. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_fill.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index aaa778300..d5843b7f5 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -200,10 +200,10 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); - if (nbox * 4 * 2 > ARRAY_SIZE(vertices)) { + if (nbox > valid_nbox) { int allocated_box; - if (nbox * 6 > GLAMOR_COMPOSITE_VBO_VERT_CNT) { + if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) { allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; } else From ec3ab2f67baa00326a4964ed2047e8a137915578 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Jan 2014 07:01:17 +0800 Subject: [PATCH 13/33] glamor: Rename a variable to be more descriptive. The "valid_" prefix was used above to describe our allocation that gets reused multiple times, which is totally unrelated. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_fill.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index d5843b7f5..12b8c3732 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -226,17 +226,17 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) while (nbox) { int box_cnt, i; - float *valid_vertices; + float *next_box; - valid_vertices = pvertices; + next_box = pvertices; box_cnt = nbox > valid_nbox ? valid_nbox : nbox; for (i = 0; i < box_cnt; i++) { glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, box[i].x1, box[i].y1, box[i].x2, box[i].y2, glamor_priv->yInverted, - valid_vertices); - valid_vertices += 4 * 2; + next_box); + next_box += 4 * 2; } if (box_cnt == 1) glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4); From 53996e252e51c8053537f485616a078cb7b0f738 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Jan 2014 07:05:02 +0800 Subject: [PATCH 14/33] glamor: Rename more solid fill variables to clean up the code. Now the error path of allocation is more obvious: We leave things in the a-few-boxes-at-a-time stack memory state. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_fill.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index 12b8c3732..f8b39a56f 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -187,9 +187,9 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); GLfloat xscale, yscale; - float vertices[32]; - float *pvertices = vertices; - int valid_nbox = ARRAY_SIZE(vertices) / (4 * 2); + float stack_vertices[32]; + float *vertices = stack_vertices; + int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2); glamor_set_destination_pixmap_priv_nc(pixmap_priv); @@ -201,19 +201,17 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); if (nbox > valid_nbox) { - int allocated_box; + int allocated_nbox; + float *new_vertices; - if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) { - allocated_box = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; - } + if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6) + allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6; else - allocated_box = nbox; - pvertices = malloc(allocated_box * 4 * 2 * sizeof(float)); - if (pvertices) - valid_nbox = allocated_box; - else { - pvertices = vertices; - valid_nbox = ARRAY_SIZE(vertices) / (4 * 2); + allocated_nbox = nbox; + new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float)); + if (new_vertices) { + vertices = new_vertices; + valid_nbox = allocated_nbox; } } @@ -221,14 +219,14 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, - GL_FALSE, 2 * sizeof(float), pvertices); + GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); while (nbox) { int box_cnt, i; float *next_box; - next_box = pvertices; + next_box = vertices; box_cnt = nbox > valid_nbox ? valid_nbox : nbox; for (i = 0; i < box_cnt; i++) { glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale, @@ -253,8 +251,8 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) box += box_cnt; } - if (pvertices != vertices) - free(pvertices); + if (vertices != stack_vertices) + free(vertices); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glUseProgram(0); From 575e3e1bf08c418430da86228d2774e8fda4b8c0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 6 Jan 2014 07:22:47 +0800 Subject: [PATCH 15/33] glamor: Fix up doxygen for glamor_fill.c. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_fill.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index f8b39a56f..a3f0f29e9 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -27,10 +27,14 @@ #include "glamor_priv.h" -/** @file glamor_fillspans.c +/** @file glamor_fill.c * * GC fill implementation, based loosely on fb_fill.c */ + +/** + * Fills the given rectangle of a drawable with the GC's fill style. + */ Bool glamor_fill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height, Bool fallback) @@ -261,6 +265,12 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) glamor_priv->render_idle_cnt = 0; } +/** + * Fills the given rectangles of pixmap with an X pixel value. + * + * This is a helper used by other code after clipping and translation + * of coordinates to a glamor backing pixmap. + */ Bool glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, unsigned long fg_pixel) @@ -308,6 +318,12 @@ glamor_solid_boxes(PixmapPtr pixmap, return TRUE; } +/** + * Fills a rectangle of a pixmap with an X pixel value. + * + * This is a helper used by other glamor code mostly for clearing of + * buffers to 0. + */ Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height, unsigned char alu, unsigned long planemask, unsigned long fg_pixel) From f7cd1189d068471373f51d932c558f8151182d58 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 10 Jan 2014 22:42:02 +0800 Subject: [PATCH 16/33] glamor: Replace some goofy enum-likes with a real enum. This unpacks the bitfield into an int size, but my experience has been that packing bitfields doesn't matter for performance. v2: Convert more comparisons against numbers or implicit bool comparisons to comparisons against the enum names, and fix up some comments. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_copyarea.c | 2 +- glamor/glamor_core.c | 3 ++- glamor/glamor_fbo.c | 2 +- glamor/glamor_pixmap.c | 2 +- glamor/glamor_priv.h | 32 +++++++++++++++++++------------- glamor/glamor_render.c | 4 ++-- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index d6bcacd36..d03f708f3 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -137,7 +137,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - if (!src_pixmap_priv->base.gl_fbo) { + if (src_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) { #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); return FALSE; diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 58838095b..6b10e97ab 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -42,7 +42,8 @@ glamor_get_drawable_location(const DrawablePtr drawable) glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); - if (pixmap_priv == NULL || pixmap_priv->base.gl_fbo == 0) + if (pixmap_priv == NULL || + pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) return 'm'; if (pixmap_priv->base.fbo->fb == glamor_priv->screen_fbo) return 's'; diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c index 281cf830e..640b6fd81 100644 --- a/glamor/glamor_fbo.c +++ b/glamor/glamor_fbo.c @@ -505,7 +505,7 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo) case GLAMOR_TEXTURE_LARGE: case GLAMOR_TEXTURE_ONLY: case GLAMOR_TEXTURE_DRM: - pixmap_priv->base.gl_fbo = 1; + pixmap_priv->base.gl_fbo = GLAMOR_FBO_NORMAL; if (fbo->tex != 0) pixmap_priv->base.gl_tex = 1; else { diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 119e4d9d1..6ecabb51d 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -886,7 +886,7 @@ glamor_pixmap_upload_prepare(PixmapPtr pixmap, GLenum format, int no_alpha, pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); - if (pixmap_priv->base.gl_fbo) + if (pixmap_priv->base.gl_fbo != GLAMOR_FBO_UNATTACHED) return 0; if (pixmap_priv->base.fbo diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 4dc2c7561..0c699900a 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -291,8 +291,21 @@ typedef enum glamor_access { GLAMOR_ACCESS_WO, } glamor_access_t; -#define GLAMOR_FBO_NORMAL 1 -#define GLAMOR_FBO_DOWNLOADED 2 +enum glamor_fbo_state { + /** There is no storage attached to the pixmap. */ + GLAMOR_FBO_UNATTACHED, + /** + * The pixmap has FBO storage attached, but devPrivate.ptr doesn't + * point at anything. + */ + GLAMOR_FBO_NORMAL, + /** + * The FBO is present and can be accessed as a linear memory + * mapping through devPrivate.ptr. + */ + GLAMOR_FBO_DOWNLOADED, +}; + /* glamor_pixmap_fbo: * @list: to be used to link to the cache pool list. * @expire: when push to cache pool list, set a expire count. @@ -324,12 +337,6 @@ typedef struct glamor_pixmap_fbo { /* * glamor_pixmap_private - glamor pixmap's private structure. - * @gl_fbo: - * 0 - The pixmap doesn't has a fbo attached to it. - * GLAMOR_FBO_NORMAL - The pixmap has a fbo and can be accessed normally. - * GLAMOR_FBO_DOWNLOADED - The pixmap has a fbo and already downloaded to - * CPU, so it can only be treated as a in-memory pixmap - * if this bit is set. * @gl_tex: The pixmap is in a gl texture originally. * @is_picture: The drawable is attached to a picture. * @pict_format: the corresponding picture's format. @@ -403,7 +410,7 @@ typedef struct glamor_pixmap_clipped_regions { typedef struct glamor_pixmap_private_base { glamor_pixmap_type_t type; - unsigned char gl_fbo:2; + enum glamor_fbo_state gl_fbo; unsigned char is_picture:1; unsigned char gl_tex:1; glamor_pixmap_fbo *fbo; @@ -777,7 +784,7 @@ glamor_put_vbo_space(ScreenPtr screen); * One copy of current pixmap's texture will be put into * the pixmap->devPrivate.ptr. Will use pbo to map to * the pointer if possible. - * The pixmap must be a gl texture pixmap. gl_fbo and + * The pixmap must be a gl texture pixmap. gl_fbo must be GLAMOR_FBO_NORMAL and * gl_tex must be 1. Used by glamor_prepare_access. * */ @@ -792,9 +799,8 @@ void *glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, int x, int y, int w, * glamor_download_pixmap_to_cpu to its original * gl texture. Used by glamor_finish_access. * - * The pixmap must be - * in texture originally. In other word, the gl_fbo - * must be 1. + * The pixmap must originally be a texture -- gl_fbo must be + * GLAMOR_FBO_NORMAL. **/ void glamor_restore_pixmap_to_texture(PixmapPtr pixmap); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 086526d2e..8569ae2fe 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -961,7 +961,7 @@ glamor_composite_choose_shader(CARD8 op, * Does it need special handle? */ glamor_fallback("source == dest\n"); } - if (source_pixmap_priv->base.gl_fbo == 0) { + if (source_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) { /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex * equal to zero when the pixmap is screen pixmap. Then we may * refer the tex zero directly latter in the composition. @@ -982,7 +982,7 @@ glamor_composite_choose_shader(CARD8 op, glamor_fallback("mask == dest\n"); goto fail; } - if (mask_pixmap_priv->base.gl_fbo == 0) { + if (mask_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) { #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD mask_status = GLAMOR_UPLOAD_PENDING; #else From c36b903f240664f7222cfefc480e60fca936de6a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 13 Mar 2014 10:09:08 -0700 Subject: [PATCH 17/33] glamor: Drop stale comment. The old Xephyr codebase was using the GL window system framebuffer for the screen pixmap, but that meant you couldn't texture from it to do operations sourcing from the screen, so in the version that landed I instead had the screen just be a plain texture. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- glamor/glamor_render.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 8569ae2fe..f93aac1ef 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -962,10 +962,6 @@ glamor_composite_choose_shader(CARD8 op, glamor_fallback("source == dest\n"); } if (source_pixmap_priv->base.gl_fbo == GLAMOR_FBO_UNATTACHED) { - /* XXX in Xephyr, we may have gl_fbo equal to 1 but gl_tex - * equal to zero when the pixmap is screen pixmap. Then we may - * refer the tex zero directly latter in the composition. - * It seems that it works fine, but it may have potential problem*/ #ifdef GLAMOR_PIXMAP_DYNAMIC_UPLOAD source_status = GLAMOR_UPLOAD_PENDING; #else From d86eacedab443f172baccf544d17e09090f71f3c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 10 Jan 2014 23:39:02 +0800 Subject: [PATCH 18/33] glamor: Drop unused GLAMOR_ACCESS_WO. Nothing was using it, and it was going to complicate the glamor_prepare_access bugfixing I'm going to do next. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_pixmap.c | 11 +---------- glamor/glamor_priv.h | 1 - 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 6ecabb51d..bc7be9dd7 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -1216,8 +1216,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format, gl_access = GL_READ_ONLY; gl_usage = GL_STREAM_READ; break; - case GLAMOR_ACCESS_WO: - return bits; case GLAMOR_ACCESS_RW: gl_access = GL_READ_WRITE; gl_usage = GL_DYNAMIC_DRAW; @@ -1472,8 +1470,7 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access) stride = pixmap->devKind; - if (access == GLAMOR_ACCESS_WO - || glamor_priv->gl_flavor == GLAMOR_GL_ES2 + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2 || (!glamor_priv->has_pack_invert && !glamor_priv->yInverted) || pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { data = malloc(stride * pixmap->drawable.height); @@ -1603,12 +1600,6 @@ glamor_get_sub_pixmap(PixmapPtr pixmap, int x, int y, int w, int h, return NULL; w = (x + w) > pixmap->drawable.width ? (pixmap->drawable.width - x) : w; h = (y + h) > pixmap->drawable.height ? (pixmap->drawable.height - y) : h; - if (access == GLAMOR_ACCESS_WO) { - sub_pixmap = glamor_create_pixmap(pixmap->drawable.pScreen, w, h, - pixmap->drawable.depth, - GLAMOR_CREATE_PIXMAP_CPU); - return sub_pixmap; - } glamor_priv = glamor_get_screen_private(pixmap->drawable.pScreen); pixmap_priv = glamor_get_pixmap_private(pixmap); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 0c699900a..3cc0d2407 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -288,7 +288,6 @@ typedef struct glamor_screen_private { typedef enum glamor_access { GLAMOR_ACCESS_RO, GLAMOR_ACCESS_RW, - GLAMOR_ACCESS_WO, } glamor_access_t; enum glamor_fbo_state { From 4c9a20072552c52b3763bd73e7a7e9b9cb8b4993 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 10 Jan 2014 23:43:09 +0800 Subject: [PATCH 19/33] glamor: Allow nested mapping of pixmaps. The common pattern is to do nested if statements making calls to prepare_access() and then pop those mappings back off in each set of braces. Some cases checked for src == dst to avoid leaking mappings, but others didn't. Others didn't even do the nested mappings, so a failure in the outer map would result in trying to umap the inner and failing. By allowing nested mappings, we can fix both problems by not requiring the care from the caller, plus we can allow a simpler nesting of all the prepares in one if statement. v2: Add a comment about nested unmap behavior, and just reuse the glamor_access_t enum. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_core.c | 23 ++++++++++++++++++++++- glamor/glamor_priv.h | 6 ++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 6b10e97ab..a6a603973 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -106,6 +106,19 @@ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (pixmap->devPrivate.ptr) { + /* Already mapped, nothing needs to be done. Note that we + * aren't allowing promotion from RO to RW, because it would + * require re-mapping the PBO. + */ + assert(!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) || + access == GLAMOR_ACCESS_RO || + pixmap_priv->base.mapped_for_write); + return TRUE; + } + pixmap_priv->base.map_access = access; return glamor_download_pixmap_to_cpu(pixmap, access); } @@ -301,7 +314,15 @@ glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode) if (!GLAMOR_PIXMAP_PRIV_HAS_FBO_DOWNLOADED(pixmap_priv)) return; - if (access_mode != GLAMOR_ACCESS_RO) { + /* If we are doing a series of unmaps from a nested map, we're + * done. None of the callers do any rendering to maps after + * starting an unmap sequence, so we don't need to delay until the + * last nested unmap. + */ + if (!pixmap->devPrivate.ptr) + return; + + if (pixmap_priv->base.map_access == GLAMOR_ACCESS_RW) { glamor_restore_pixmap_to_texture(pixmap); } diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 3cc0d2407..776de06ef 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -410,6 +410,12 @@ typedef struct glamor_pixmap_clipped_regions { typedef struct glamor_pixmap_private_base { glamor_pixmap_type_t type; enum glamor_fbo_state gl_fbo; + /** + * If devPrivate.ptr is non-NULL (meaning we're within + * glamor_prepare_access), determies whether we should re-upload + * that data on glamor_finish_access(). + */ + glamor_access_t map_access; unsigned char is_picture:1; unsigned char gl_tex:1; glamor_pixmap_fbo *fbo; From 93f1824a0b19346f0e1759bedfa9cf10772067af Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 11 Jan 2014 00:00:00 +0800 Subject: [PATCH 20/33] glamor: Rely on nested mappings to handle src==dst and !prepare bugs. Now that the core deals with that for us, we can avoid all this extra carefulness. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_addtraps.c | 2 +- glamor/glamor_copyarea.c | 14 ++++++-------- glamor/glamor_copyplane.c | 13 +++++++------ glamor/glamor_core.c | 17 ++++++++--------- glamor/glamor_fill.c | 11 +++++------ glamor/glamor_fillspans.c | 11 +++++------ glamor/glamor_getspans.c | 2 +- glamor/glamor_picture.c | 4 ++-- glamor/glamor_polyfillrect.c | 11 +++++------ glamor/glamor_polylines.c | 11 +++++------ glamor/glamor_priv.h | 4 ++-- glamor/glamor_putimage.c | 2 +- glamor/glamor_render.c | 25 ++++++++++--------------- glamor/glamor_setspans.c | 2 +- glamor/glamor_triangles.c | 15 ++++++--------- glamor/glamor_utils.h | 33 ++++++++++++++++----------------- 16 files changed, 81 insertions(+), 96 deletions(-) diff --git a/glamor/glamor_addtraps.c b/glamor/glamor_addtraps.c index 655d87e3d..fdc0f4232 100644 --- a/glamor/glamor_addtraps.c +++ b/glamor/glamor_addtraps.c @@ -40,8 +40,8 @@ _glamor_add_traps(PicturePtr pPicture, if (glamor_prepare_access_picture(pPicture, GLAMOR_ACCESS_RW)) { fbAddTraps(pPicture, x_off, y_off, ntrap, traps); - glamor_finish_access_picture(pPicture, GLAMOR_ACCESS_RW); } + glamor_finish_access_picture(pPicture); return TRUE; } diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index d03f708f3..ae3264dd2 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -570,15 +570,13 @@ _glamor_copy_n_to_n(DrawablePtr src, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); - if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { - if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { - fbCopyNtoN(src, dst, gc, box, nbox, - dx, dy, reverse, upsidedown, bitplane, closure); - if (dst != src) - glamor_finish_access(src, GLAMOR_ACCESS_RO); - } - glamor_finish_access(dst, GLAMOR_ACCESS_RW); + if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && + glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + fbCopyNtoN(src, dst, gc, box, nbox, + dx, dy, reverse, upsidedown, bitplane, closure); } + glamor_finish_access(src); + glamor_finish_access(dst); ok = TRUE; done: diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c index c42d33e94..50e9cf303 100644 --- a/glamor/glamor_copyplane.c +++ b/glamor/glamor_copyplane.c @@ -38,12 +38,13 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, && glamor_ddx_fallback_check_pixmap(pDst)) goto fail; - glamor_prepare_access(pDst, GLAMOR_ACCESS_RW); - glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO); - *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, bitPlane); - glamor_finish_access(pSrc, GLAMOR_ACCESS_RO); - glamor_finish_access(pDst, GLAMOR_ACCESS_RW); + if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) && + glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO)) { + *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, + dstx, dsty, bitPlane); + } + glamor_finish_access(pSrc); + glamor_finish_access(pDst); return TRUE; fail: diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index a6a603973..61025c3bd 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -304,7 +304,7 @@ glamor_fini_finish_access_shaders(ScreenPtr screen) } void -glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode) +glamor_finish_access(DrawablePtr drawable) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); @@ -370,7 +370,7 @@ glamor_prepare_access_gc(GCPtr gc) if (!glamor_prepare_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO)) { if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&gc->stipple->drawable); return FALSE; } } @@ -384,9 +384,9 @@ void glamor_finish_access_gc(GCPtr gc) { if (gc->fillStyle == FillTiled) - glamor_finish_access(&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&gc->tile.pixmap->drawable); if (gc->stipple) - glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&gc->stipple->drawable); } Bool @@ -460,7 +460,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) (&old_tile->drawable, GLAMOR_ACCESS_RO)) { new_tile = fb24_32ReformatTile(old_tile, drawable->bitsPerPixel); - glamor_finish_access(&old_tile->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&old_tile->drawable); } } if (new_tile) { @@ -483,8 +483,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) if (glamor_prepare_access (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) { fbPadPixmap(gc->tile.pixmap); - glamor_finish_access - (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW); + glamor_finish_access(&gc->tile.pixmap->drawable); } } } @@ -500,7 +499,7 @@ glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) */ if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { fbValidateGC(gc, changes, drawable); - glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW); + glamor_finish_access(&gc->stipple->drawable); } } else { @@ -544,7 +543,7 @@ glamor_bitmap_to_region(PixmapPtr pixmap) if (!glamor_prepare_access(&pixmap->drawable, GLAMOR_ACCESS_RO)) return NULL; ret = fbPixmapToRegion(pixmap); - glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&pixmap->drawable); return ret; } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index a3f0f29e9..d91dafb83 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -112,13 +112,12 @@ glamor_fill(DrawablePtr drawable, x = 0; y = 0; } - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_gc(gc)) { - fbFill(drawable, gc, x, y, width, height); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbFill(drawable, gc, x, y, width, height); } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); if (sub_pixmap != NULL) { if (gc->fillStyle != FillSolid) { diff --git a/glamor/glamor_fillspans.c b/glamor/glamor_fillspans.c index 7261d2842..8cbd79f6d 100644 --- a/glamor/glamor_fillspans.c +++ b/glamor/glamor_fillspans.c @@ -79,13 +79,12 @@ _glamor_fill_spans(DrawablePtr drawable, } glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_gc(gc)) { - fbFillSpans(drawable, gc, n, points, widths, sorted); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbFillSpans(drawable, gc, n, points, widths, sorted); } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); ret = TRUE; done: diff --git a/glamor/glamor_getspans.c b/glamor/glamor_getspans.c index ff58725d6..42df87f3d 100644 --- a/glamor/glamor_getspans.c +++ b/glamor/glamor_getspans.c @@ -69,8 +69,8 @@ _glamor_get_spans(DrawablePtr drawable, ret = TRUE; if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) { fbGetSpans(drawable, wmax, points, widths, count, dst); - glamor_finish_access(drawable, GLAMOR_ACCESS_RO); } + glamor_finish_access(drawable); done: return ret; } diff --git a/glamor/glamor_picture.c b/glamor/glamor_picture.c index 8bbe2e98b..5fdc5f9b0 100644 --- a/glamor/glamor_picture.c +++ b/glamor/glamor_picture.c @@ -55,12 +55,12 @@ glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access) } void -glamor_finish_access_picture(PicturePtr picture, glamor_access_t access) +glamor_finish_access_picture(PicturePtr picture) { if (!picture || !picture->pDrawable) return; - glamor_finish_access(picture->pDrawable, access); + glamor_finish_access(picture->pDrawable); } /* diff --git a/glamor/glamor_polyfillrect.c b/glamor/glamor_polyfillrect.c index a25fc4ed5..1e361a44f 100644 --- a/glamor/glamor_polyfillrect.c +++ b/glamor/glamor_polyfillrect.c @@ -96,13 +96,12 @@ _glamor_poly_fill_rect(DrawablePtr drawable, glamor_fallback(" to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_gc(gc)) { - fbPolyFillRect(drawable, gc, nrect, prect); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbPolyFillRect(drawable, gc, nrect, prect); } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); ret = TRUE; done: diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index b94161760..697fc9e74 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -105,13 +105,12 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, return FALSE; if (gc->lineWidth == 0) { - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_gc(gc)) { - fbPolyLine(drawable, gc, mode, n, points); - glamor_finish_access_gc(gc); - } - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { + fbPolyLine(drawable, gc, mode, n, points); } + glamor_finish_access_gc(gc); + glamor_finish_access(drawable); } else { wide_line: diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 776de06ef..fed159789 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -578,7 +578,7 @@ void glamor_copy_window(WindowPtr win, DDXPointRec old_origin, /* glamor_core.c */ Bool glamor_prepare_access(DrawablePtr drawable, glamor_access_t access); -void glamor_finish_access(DrawablePtr drawable, glamor_access_t access); +void glamor_finish_access(DrawablePtr drawable); Bool glamor_prepare_access_window(WindowPtr window); void glamor_finish_access_window(WindowPtr window); Bool glamor_prepare_access_gc(GCPtr gc); @@ -904,7 +904,7 @@ void glamor_set_window_pixmap(WindowPtr pWindow, PixmapPtr pPixmap); Bool glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access); -void glamor_finish_access_picture(PicturePtr picture, glamor_access_t access); +void glamor_finish_access_picture(PicturePtr picture); void glamor_destroy_picture(PicturePtr picture); diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index 702e89f14..a4f97cdf7 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -229,8 +229,8 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, fail: if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); } + glamor_finish_access(drawable); } #endif diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index f93aac1ef..65f377863 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1784,22 +1784,17 @@ _glamor_composite(CARD8 op, if (mask && mask->pDrawable && !mask->transform) GET_SUB_PICTURE(mask, GLAMOR_ACCESS_RO); - if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW)) { - if (source_pixmap == dest_pixmap || glamor_prepare_access_picture - (source, GLAMOR_ACCESS_RO)) { - if (!mask || glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) { - fbComposite(op, - source, mask, dest, - x_source, y_source, - x_mask, y_mask, x_dest, y_dest, width, height); - if (mask) - glamor_finish_access_picture(mask, GLAMOR_ACCESS_RO); - } - if (source_pixmap != dest_pixmap) - glamor_finish_access_picture(source, GLAMOR_ACCESS_RO); - } - glamor_finish_access_picture(dest, GLAMOR_ACCESS_RW); + if (glamor_prepare_access_picture(dest, GLAMOR_ACCESS_RW) && + glamor_prepare_access_picture(source, GLAMOR_ACCESS_RO) && + glamor_prepare_access_picture(mask, GLAMOR_ACCESS_RO)) { + fbComposite(op, + source, mask, dest, + x_source, y_source, + x_mask, y_mask, x_dest, y_dest, width, height); } + glamor_finish_access_picture(mask); + glamor_finish_access_picture(source); + glamor_finish_access_picture(dest); #define PUT_SUB_PICTURE(p, access) do { \ if (sub_ ##p ##_pixmap != NULL) { \ diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 22fe88ce5..664f8acc4 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -88,8 +88,8 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted); - glamor_finish_access(drawable, GLAMOR_ACCESS_RW); } + glamor_finish_access(drawable); ret = TRUE; done: diff --git a/glamor/glamor_triangles.c b/glamor/glamor_triangles.c index 693eef10f..b89cb2de7 100644 --- a/glamor/glamor_triangles.c +++ b/glamor/glamor_triangles.c @@ -41,16 +41,13 @@ _glamor_triangles(CARD8 op, || glamor_ddx_fallback_check_pixmap(pSrc->pDrawable))) return FALSE; - if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) { - - fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris); - - glamor_finish_access_picture(pSrc, GLAMOR_ACCESS_RO); - } - - glamor_finish_access_picture(pDst, GLAMOR_ACCESS_RW); + if (glamor_prepare_access_picture(pDst, GLAMOR_ACCESS_RW) && + glamor_prepare_access_picture(pSrc, GLAMOR_ACCESS_RO)) { + fbTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntris, tris); } + glamor_finish_access_picture(pSrc); + glamor_finish_access_picture(pDst); + return TRUE; } diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index f9550b73c..53b7d9bec 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -1177,7 +1177,7 @@ glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h) default: ErrorF("dump depth %d, not implemented.\n", pixmap->drawable.depth); } - glamor_finish_access(&pixmap->drawable, GLAMOR_ACCESS_RO); + glamor_finish_access(&pixmap->drawable); } static inline void @@ -1318,13 +1318,12 @@ glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, { assert(pixmap1->drawable.depth == pixmap2->drawable.depth); - glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); - glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); - - _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs); - - glamor_finish_access(&pixmap1->drawable, GLAMOR_ACCESS_RO); - glamor_finish_access(&pixmap2->drawable, GLAMOR_ACCESS_RO); + if (glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO) && + glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO)) { + _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs); + } + glamor_finish_access(&pixmap1->drawable); + glamor_finish_access(&pixmap2->drawable); } /* This function is used to compare two pictures. @@ -1432,9 +1431,6 @@ glamor_compare_pictures(ScreenPtr screen, return; } - glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); - glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); - if ((fst_type == SourcePictTypeLinear) || (fst_type == SourcePictTypeRadial) || (fst_type == SourcePictTypeConical) || @@ -1444,12 +1440,15 @@ glamor_compare_pictures(ScreenPtr screen, x_source = y_source = 0; } - _glamor_compare_pixmaps(fst_pixmap, snd_pixmap, - x_source, y_source, - width, height, fst_picture->format, all, diffs); - - glamor_finish_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO); - glamor_finish_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO); + if (glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO) && + glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO)) { + _glamor_compare_pixmaps(fst_pixmap, snd_pixmap, + x_source, y_source, + width, height, fst_picture->format, + all, diffs); + } + glamor_finish_access(&fst_pixmap->drawable); + glamor_finish_access(&snd_pixmap->drawable); if (fst_generated) glamor_destroy_picture(fst_picture); From ab68982dcc53d29d5e3c5ea092bd91dab09e54c9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 11 Jan 2014 00:06:21 +0800 Subject: [PATCH 21/33] glamor: Add missing prepares on the GC during fb fallbacks. We had regressions in CopyPlane reported by xts5, because we were (successfully!) dereferencing the null pixmap->devPrivate.ptr for a tile or stipple without having done a prepare. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_copyarea.c | 4 +++- glamor/glamor_copyplane.c | 4 +++- glamor/glamor_putimage.c | 4 +++- glamor/glamor_setspans.c | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index ae3264dd2..0b170dc79 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -571,10 +571,12 @@ _glamor_copy_n_to_n(DrawablePtr src, glamor_get_drawable_location(dst)); if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && - glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + glamor_prepare_access(src, GLAMOR_ACCESS_RO) && + glamor_prepare_access_gc(gc)) { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } + glamor_finish_access_gc(gc); glamor_finish_access(src); glamor_finish_access(dst); ok = TRUE; diff --git a/glamor/glamor_copyplane.c b/glamor/glamor_copyplane.c index 50e9cf303..2bd2de30d 100644 --- a/glamor/glamor_copyplane.c +++ b/glamor/glamor_copyplane.c @@ -39,10 +39,12 @@ _glamor_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, goto fail; if (glamor_prepare_access(pDst, GLAMOR_ACCESS_RW) && - glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO)) { + glamor_prepare_access(pSrc, GLAMOR_ACCESS_RO) && + glamor_prepare_access_gc(pGC)) { *pRegion = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); } + glamor_finish_access_gc(pGC); glamor_finish_access(pSrc); glamor_finish_access(pDst); return TRUE; diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index a4f97cdf7..b77238cfb 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -227,9 +227,11 @@ glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, glamor_fallback(": to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); fail: - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) && + glamor_prepare_access_gc(gc)) { fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); } + glamor_finish_access_gc(gc); glamor_finish_access(drawable); } #endif diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index 664f8acc4..ced302a50 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -86,9 +86,11 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) { fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted); } + glamor_finish_access_gc(gc); glamor_finish_access(drawable); ret = TRUE; From b885a639144cdadcb0dae8249a168db158770604 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 5 Jan 2014 21:54:48 +0800 Subject: [PATCH 22/33] glamor: Improve the performance of PushPixels by, well, pushing pixels. Otherwise, mi will fall back to GetSpans()ing the bitmap, walking the bitmap, computing spans to be filled, and calling FillSpans(). Improves x11perf -f8text by 759.373% +/- 3.33096% (n=166) Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_glyphblt.c | 115 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index 6f754ce2b..0a99a951c 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -90,16 +90,131 @@ glamor_poly_glyph_blt_nf(DrawablePtr pDrawable, GCPtr pGC, pglyphBase, FALSE); } +static Bool +glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, + DrawablePtr drawable, int w, int h, int x, int y) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + uint8_t *bitmap_data = bitmap->devPrivate.ptr; + int bitmap_stride = bitmap->devKind; + int off_x, off_y; + int yy, xx; + GLfloat xscale, yscale; + float color[4]; + unsigned long fg_pixel = gc->fgPixel; + float *points, *next_point; + int num_points = 0; + char *vbo_offset; + RegionPtr clip; + + if (w * h > MAXINT / (2 * sizeof(float))) + return FALSE; + + if (gc->fillStyle != FillSolid) { + glamor_fallback("gc fillstyle not solid\n"); + return FALSE; + } + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return FALSE; + + glamor_get_context(glamor_priv); + if (!glamor_set_alu(screen, gc->alu)) { + if (gc->alu == GXclear) + fg_pixel = 0; + else { + glamor_fallback("unsupported alu %x\n", gc->alu); + glamor_put_context(glamor_priv); + return FALSE; + } + } + + if (!glamor_set_planemask(pixmap, gc->planemask)) { + glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__); + glamor_put_context(glamor_priv); + return FALSE; + } + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); + + glUseProgram(glamor_priv->solid_prog); + + glamor_get_rgba_from_pixel(fg_pixel, + &color[0], &color[1], &color[2], &color[3], + format_for_pixmap(pixmap)); + glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); + + points = glamor_get_vbo_space(screen, w * h * sizeof(float) * 2, + &vbo_offset); + next_point = points; + + clip = fbGetCompositeClip(gc); + + /* Note that because fb sets miTranslate in the GC, our incoming X + * and Y are in screen coordinate space (same for spans, but not + * other operations). + */ + for (yy = 0; yy < h; yy++) { + uint8_t *bitmap_row = bitmap_data + yy * bitmap_stride; + for (xx = 0; xx < w; xx++) { + if (bitmap_row[xx / 8] & (1 << xx % 8) && + RegionContainsPoint(clip, + x + xx, + y + yy, + NULL)) { + next_point[0] = v_from_x_coord_x(xscale, x + xx + off_x + 0.5); + if (glamor_priv->yInverted) + next_point[1] = v_from_x_coord_y_inverted(yscale, y + yy + off_y + 0.5); + else + next_point[1] = v_from_x_coord_y(yscale, y + yy + off_y + 0.5); + + next_point += 2; + num_points++; + } + } + } + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), + vbo_offset); + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + glamor_put_vbo_space(screen); + + glDrawArrays(GL_POINTS, 0, num_points); + + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glUseProgram(0); + + glamor_put_context(glamor_priv); + + return TRUE; +} + static Bool _glamor_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y, Bool fallback) { + glamor_pixmap_private *pixmap_priv; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) && glamor_ddx_fallback_check_pixmap(&pBitmap->drawable) && glamor_ddx_fallback_check_gc(pGC)) return FALSE; + pixmap_priv = glamor_get_pixmap_private(pBitmap); + if (pixmap_priv->type == GLAMOR_MEMORY) { + if (glamor_push_pixels_points(pGC, pBitmap, pDrawable, w, h, x, y)) + return TRUE; + } + miPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); return TRUE; } From b6953045566dae15437d4220e68986db7a6b4ca7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 9 Jan 2014 10:53:04 +0800 Subject: [PATCH 23/33] glamor: Improve the performance of PolyGlyphBlt. Using the same idea as the previous PushPixels code, just make points for each point in the glyph. This is an advantage over the pushpixels fallback because we can batch the BO mappings and draw calls across glyphs. Improves performance of x11perf -f8text by 773.389% +/- 3.50754% (n=10). Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_glyphblt.c | 138 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index 0a99a951c..5d785a069 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -27,6 +27,141 @@ */ #include "glamor_priv.h" +#include + +static Bool +glamor_poly_glyph_blt_pixels(DrawablePtr drawable, GCPtr gc, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + int off_x, off_y; + GLfloat xscale, yscale; + float color[4]; + unsigned long fg_pixel = gc->fgPixel; + char *vbo_offset; + RegionPtr clip; + int num_points, max_points; + float *points = NULL; + + x += drawable->x; + y += drawable->y; + + if (gc->fillStyle != FillSolid) { + glamor_fallback("gc fillstyle not solid\n"); + return FALSE; + } + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return FALSE; + + glamor_get_context(glamor_priv); + if (!glamor_set_alu(screen, gc->alu)) { + if (gc->alu == GXclear) + fg_pixel = 0; + else { + glamor_fallback("unsupported alu %x\n", gc->alu); + glamor_put_context(glamor_priv); + return FALSE; + } + } + + if (!glamor_set_planemask(pixmap, gc->planemask)) { + glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__); + glamor_put_context(glamor_priv); + return FALSE; + } + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + + glamor_set_destination_pixmap_priv_nc(pixmap_priv); + pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale); + + glUseProgram(glamor_priv->solid_prog); + + glamor_get_rgba_from_pixel(fg_pixel, + &color[0], &color[1], &color[2], &color[3], + format_for_pixmap(pixmap)); + glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color); + + clip = fbGetCompositeClip(gc); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + + max_points = 500; + num_points = 0; + while (nglyph--) { + CharInfoPtr charinfo = *ppci++; + int w = GLYPHWIDTHPIXELS(charinfo); + int h = GLYPHHEIGHTPIXELS(charinfo); + uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo); + + if (w && h) { + int glyph_x = x + charinfo->metrics.leftSideBearing; + int glyph_y = y - charinfo->metrics.ascent; + int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo); + int xx, yy; + + for (yy = 0; yy < h; yy++) { + uint8_t *glyph_row = glyphbits + glyph_stride * yy; + for (xx = 0; xx < w; xx++) { + int pt_x_i = glyph_x + xx; + int pt_y_i = glyph_y + yy; + float pt_x_f, pt_y_f; + if (!(glyph_row[xx / 8] & (1 << xx % 8))) + continue; + + if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL)) + continue; + + if (!num_points) { + points = glamor_get_vbo_space(screen, + max_points * 2 * sizeof(float), + &vbo_offset); + + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, + GL_FALSE, 2 * sizeof(float), + vbo_offset); + } + + pt_x_f = v_from_x_coord_x(xscale, pt_x_i + off_x + 0.5); + if (glamor_priv->yInverted) + pt_y_f = v_from_x_coord_y_inverted(yscale, pt_y_i + off_y + 0.5); + else + pt_y_f = v_from_x_coord_y(yscale, pt_y_i + off_y + 0.5); + + points[num_points * 2 + 0] = pt_x_f; + points[num_points * 2 + 1] = pt_y_f; + num_points++; + + if (num_points == max_points) { + glamor_put_vbo_space(screen); + glDrawArrays(GL_POINTS, 0, num_points); + num_points = 0; + } + } + } + } + + x += charinfo->metrics.characterWidth; + } + + if (num_points) { + glamor_put_vbo_space(screen); + glDrawArrays(GL_POINTS, 0, num_points); + } + + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glUseProgram(0); + + glamor_put_context(glamor_priv); + + return TRUE; +} static Bool _glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, @@ -64,6 +199,9 @@ _glamor_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyphBase, Bool fallback) { + if (glamor_poly_glyph_blt_pixels(pDrawable, pGC, x, y, nglyph, ppci)) + return TRUE; + if (!fallback && glamor_ddx_fallback_check_pixmap(pDrawable) && glamor_ddx_fallback_check_gc(pGC)) return FALSE; From 923c8db7ed1adfe4689f0a36496262faca44b79d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 9 Jan 2014 11:36:30 +0800 Subject: [PATCH 24/33] glamor: Improve the performance of line fallbacks. If the lines aren't solid-filled vert/horiz solid-filled rectangles, we fall back. libreoffice has some diagonal lines, and the performance of the fallback path was atrocious. Just fall back to mi's spans instead, so that we don't do an upload/download. Improves x11perf -seg100 by 863.652% +/- 9.8968% (n=5) Signed-off-by: Eric Anholt --- glamor/glamor_polylines.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/glamor/glamor_polylines.c b/glamor/glamor_polylines.c index 697fc9e74..1adf45ddc 100644 --- a/glamor/glamor_polylines.c +++ b/glamor/glamor_polylines.c @@ -51,8 +51,9 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, /* This ends up in miSetSpans, which is accelerated as well as we * can hope X wide lines will be. */ - goto wide_line; + goto fail; } + if (gc->lineStyle != LineSolid) { glamor_fallback("non-solid fill line style %d\n", gc->lineStyle); goto fail; @@ -104,19 +105,19 @@ _glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, && glamor_ddx_fallback_check_gc(gc)) return FALSE; - if (gc->lineWidth == 0) { - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && - glamor_prepare_access_gc(gc)) { - fbPolyLine(drawable, gc, mode, n, points); - } - glamor_finish_access_gc(gc); - glamor_finish_access(drawable); - } - else { - wide_line: - /* fb calls mi functions in the lineWidth != 0 case. */ - fbPolyLine(drawable, gc, mode, n, points); + switch (gc->lineStyle) { + case LineSolid: + if (gc->lineWidth == 0) + miZeroLine(drawable, gc, mode, n, points); + else + miWideLine(drawable, gc, mode, n, points); + break; + case LineOnOffDash: + case LineDoubleDash: + miWideDash(drawable, gc, mode, n, points); + break; } + return TRUE; } From 7eb2bafe22dcc90c2fb94d2d9cae370b683dba7c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 10 Jan 2014 15:54:25 +0800 Subject: [PATCH 25/33] glamor: Fix ignoring the ALU during SetSpans(). Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_setspans.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_setspans.c b/glamor/glamor_setspans.c index ced302a50..a51e4c5be 100644 --- a/glamor/glamor_setspans.c +++ b/glamor/glamor_setspans.c @@ -48,7 +48,11 @@ _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, goto fail; } - /* XXX Shall we set alu here? */ + if (gc->alu != GXcopy) { + glamor_fallback("SetSpans with non-copy ALU.\n"); + goto fail; + } + if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; From 64146e4560fdf3c3a40d023ac8e22259915b05ad Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 11 Jan 2014 21:11:18 -0800 Subject: [PATCH 26/33] glamor: Add an assert about an invariant the upload code relies on. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_pixmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index bc7be9dd7..1bbcc551b 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -725,6 +725,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + assert(pbo || bits != 0); if (bits == NULL) glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); if (non_sub) From d07d2c3c5f95fd644ef563004dfa7f3c53904168 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 11 Jan 2014 21:26:01 -0800 Subject: [PATCH 27/33] glamor: Don't forget to unmap our PBOs before using them to upload. From the GL_ARB_vertex_buffer_object spec: After the client has specified the contents of a mapped data store, and before the data in that store are dereferenced by any GL commands, the mapping must be relinquished by calling boolean UnmapBufferARB(enum target); Our mappings were only getting reaped at PBO destroy time, after the upload. If the GL implementation wasn't coherent, it would have used stale data to do the texture upload. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor_pixmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 1bbcc551b..1c258a2b8 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -726,8 +726,10 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex, glPixelStorei(GL_UNPACK_ALIGNMENT, 4); assert(pbo || bits != 0); - if (bits == NULL) + if (bits == NULL) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + } if (non_sub) glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits); else From 1a4b24993974200e26345ea6c501d4aa093169db Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Feb 2014 15:50:03 -0800 Subject: [PATCH 28/33] glamor: Apply debug labels to our shaders. This will help tools like fips, apitrace, or INTEL_DEBUG=shader_time provide useful information about the shaders in use. Signed-off-by: Eric Anholt Reviewed-by: Markus Wick --- glamor/glamor.c | 1 + glamor/glamor_core.c | 20 +++++++++++++++++--- glamor/glamor_fill.c | 2 +- glamor/glamor_gradient.c | 4 ++-- glamor/glamor_priv.h | 4 +++- glamor/glamor_render.c | 2 +- glamor/glamor_tile.c | 2 +- glamor/glamor_trapezoid.c | 2 +- glamor/glamor_xv.c | 2 +- 9 files changed, 28 insertions(+), 11 deletions(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index 5338d45b4..a624a7bd6 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -372,6 +372,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) } } + glamor_priv->has_khr_debug = glamor_gl_has_extension("GL_KHR_debug"); glamor_priv->has_pack_invert = glamor_gl_has_extension("GL_MESA_pack_invert"); glamor_priv->has_fbo_blit = diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 61025c3bd..9e07b2b61 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -83,9 +83,10 @@ glamor_compile_glsl_prog(GLenum type, const char *source) } void -glamor_link_glsl_prog(GLint prog) +glamor_link_glsl_prog(ScreenPtr screen, GLint prog, const char *format, ...) { GLint ok; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); glLinkProgram(prog); glGetProgramiv(prog, GL_LINK_STATUS, &ok); @@ -100,6 +101,17 @@ glamor_link_glsl_prog(GLint prog) ErrorF("Failed to link: %s\n", info); FatalError("GLSL link failure\n"); } + + if (glamor_priv->has_khr_debug) { + char *label; + va_list va; + + va_start(va, format); + XNFvasprintf(&label, format, va); + glObjectLabel(GL_PROGRAM, prog, -1, label); + free(label); + va_end(va); + } } Bool @@ -256,13 +268,15 @@ glamor_init_finish_access_shaders(ScreenPtr screen) GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(glamor_priv->finish_access_prog[0], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->finish_access_prog[0]); + glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[0], + "finish access 0"); glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(glamor_priv->finish_access_prog[1], GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->finish_access_prog[1]); + glamor_link_glsl_prog(screen, glamor_priv->finish_access_prog[1], + "finish access 1"); glamor_priv->finish_access_revert[0] = glGetUniformLocation(glamor_priv->finish_access_prog[0], "revert"); diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index d91dafb83..e58b336df 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -165,7 +165,7 @@ glamor_init_solid_shader(ScreenPtr screen) glBindAttribLocation(glamor_priv->solid_prog, GLAMOR_VERTEX_POS, "v_position"); - glamor_link_glsl_prog(glamor_priv->solid_prog); + glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid"); glamor_priv->solid_color_uniform_location = glGetUniformLocation(glamor_priv->solid_prog, "color"); diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index 6a7b528f9..baa4a03f0 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -377,7 +377,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); - glamor_link_glsl_prog(gradient_prog); + glamor_link_glsl_prog(screen, gradient_prog, "radial gradient"); glUseProgram(0); @@ -590,7 +590,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(gradient_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord"); - glamor_link_glsl_prog(gradient_prog); + glamor_link_glsl_prog(screen, gradient_prog, "linear gradient"); glUseProgram(0); diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index fed159789..bc7d3f827 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -214,6 +214,7 @@ typedef struct glamor_screen_private { int has_pack_invert; int has_fbo_blit; int has_buffer_storage; + int has_khr_debug; int max_fbo_size; struct xorg_list @@ -594,7 +595,8 @@ Bool glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple, unsigned long fg_pixel, unsigned long bg_pixel, int stipple_x, int stipple_y); GLint glamor_compile_glsl_prog(GLenum type, const char *source); -void glamor_link_glsl_prog(GLint prog); +void glamor_link_glsl_prog(ScreenPtr screen, GLint prog, + const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4); void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel, GLfloat *color); diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 65f377863..2496f8429 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -332,7 +332,7 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key, glBindAttribLocation(prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); glBindAttribLocation(prog, GLAMOR_VERTEX_MASK, "v_texcoord1"); - glamor_link_glsl_prog(prog); + glamor_link_glsl_prog(screen, prog, "composite"); shader->prog = prog; diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index 7288af30e..ba7f11fc7 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -73,7 +73,7 @@ glamor_init_tile_shader(ScreenPtr screen) GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(glamor_priv->tile_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->tile_prog); + glamor_link_glsl_prog(screen, glamor_priv->tile_prog, "tile"); sampler_uniform_location = glGetUniformLocation(glamor_priv->tile_prog, "sampler"); diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c index 0064f2a24..9c39740b6 100644 --- a/glamor/glamor_trapezoid.c +++ b/glamor/glamor_trapezoid.c @@ -1357,7 +1357,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen) glBindAttribLocation(glamor_priv->trapezoid_prog, GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param"); - glamor_link_glsl_prog(glamor_priv->trapezoid_prog); + glamor_link_glsl_prog(screen, glamor_priv->trapezoid_prog, "trapezoid"); glUseProgram(0); diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index fb9045747..c0219b03e 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -109,7 +109,7 @@ glamor_init_xv_shader(ScreenPtr screen) GLAMOR_VERTEX_POS, "v_position"); glBindAttribLocation(glamor_priv->xv_prog, GLAMOR_VERTEX_SOURCE, "v_texcoord0"); - glamor_link_glsl_prog(glamor_priv->xv_prog); + glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv"); glamor_put_context(glamor_priv); } From 6227f07b69b8ab3cd39cf9d257daf2a7202b4ef5 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Tue, 11 Mar 2014 17:28:10 -0700 Subject: [PATCH 29/33] Remove duplicate assignment of repeat_type_uniform_location Flagged by cppcheck 1.64: [glamor/glamor_gradient.c:987] -> [glamor/glamor_gradient.c:991]: (performance) Variable 'repeat_type_uniform_location' is reassigned a value before the old one has been used. Signed-off-by: Alan Coopersmith Reviewed-by: Eric Anholt Signed-off-by: Eric Anholt --- glamor/glamor_gradient.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index baa4a03f0..0769eaeaa 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -983,8 +983,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, "repeat_type"); n_stop_uniform_location = glGetUniformLocation(gradient_prog, "n_stop"); A_value_uniform_location = glGetUniformLocation(gradient_prog, "A_value"); - repeat_type_uniform_location =glGetUniformLocation(gradient_prog, - "repeat_type"); c1_uniform_location = glGetUniformLocation(gradient_prog, "c1"); r1_uniform_location = glGetUniformLocation(gradient_prog, "r1"); c2_uniform_location = glGetUniformLocation(gradient_prog, "c2"); From aa2635b804e7d28322f62d802190bdf0bb799634 Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Thu, 13 Mar 2014 00:24:04 +0100 Subject: [PATCH 30/33] glamor: remove disabled code This block was disabled since 2011, so there is likely no need to keep it any more. Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- glamor/glamor_putimage.c | 199 --------------------------------------- 1 file changed, 199 deletions(-) diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c index b77238cfb..cf7197bfc 100644 --- a/glamor/glamor_putimage.c +++ b/glamor/glamor_putimage.c @@ -35,207 +35,8 @@ void glamor_init_putimage_shaders(ScreenPtr screen) { -#if 0 - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - const char *xybitmap_vs = - "uniform float x_bias;\n" - "uniform float x_scale;\n" - "uniform float y_bias;\n" - "uniform float y_scale;\n" - "varying vec2 bitmap_coords;\n" - "void main()\n" - "{\n" - " gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n" - " (gl_Vertex.y + y_bias) * y_scale,\n" - " 0,\n" - " 1);\n" - " bitmap_coords = gl_MultiTexCoord0.xy;\n" - "}\n"; - const char *xybitmap_fs = - "uniform vec4 fg, bg;\n" - "varying vec2 bitmap_coords;\n" - "uniform sampler2D bitmap_sampler;\n" - "void main()\n" - "{\n" - " float bitmap_value = texture2D(bitmap_sampler,\n" - " bitmap_coords).x;\n" - " gl_FragColor = mix(bg, fg, bitmap_value);\n" - "}\n"; - GLint fs_prog, vs_prog, prog; - GLint sampler_uniform_location; - - if (!GLEW_ARB_fragment_shader) - return; - - prog = glCreateProgram(); - vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xybitmap_vs); - fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, xybitmap_fs); - glAttachShader(prog, vs_prog); - glAttachShader(prog, fs_prog); - glamor_link_glsl_prog(prog); - - glUseProgram(prog); - sampler_uniform_location = glGetUniformLocation(prog, "bitmap_sampler"); - glUniform1i(sampler_uniform_location, 0); - - glamor_priv->put_image_xybitmap_fg_uniform_location = - glGetUniformLocation(prog, "fg"); - glamor_priv->put_image_xybitmap_bg_uniform_location = - glGetUniformLocation(prog, "bg"); - glamor_get_transform_uniform_locations(prog, - &glamor_priv-> - put_image_xybitmap_transform); - glamor_priv->put_image_xybitmap_prog = prog; - glUseProgram(0); -#endif } -/* Do an XYBitmap putimage. The bits are byte-aligned rows of bitmap - * data (where each row starts at a bit index of left_pad), and the - * destination gets filled with the gc's fg color where the bitmap is set - * and the bg color where the bitmap is unset. - * - * Implement this by passing the bitmap right through to GL, and sampling - * it to choose between fg and bg in the fragment shader. The driver may - * be exploding the bitmap up to be an 8-bit alpha texture, in which - * case we might be better off just doing the fg/bg choosing in the CPU - * and just draw the resulting texture to the destination. - */ -#if 0 - -static int -y_flip(PixmapPtr pixmap, int y) -{ - ScreenPtr screen = pixmap->drawable.pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - - if (pixmap == screen_pixmap) - return (pixmap->drawable.height - 1) - y; - else - return y; -} - -static void -glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, - int x, int y, int w, int h, int left_pad, - int image_format, char *bits) -{ - ScreenPtr screen = drawable->pScreen; - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - float fg[4], bg[4]; - GLuint tex; - unsigned int stride = PixmapBytePad(1, w + left_pad); - RegionPtr clip; - BoxPtr box; - int nbox; - float dest_coords[8]; - - const float bitmap_coords[8] = { - 0.0, 0.0, - 1.0, 0.0, - 1.0, 1.0, - 0.0, 1.0, - }; - GLfloat xscale, yscale; - glamor_pixmap_private *pixmap_priv; - - pixmap_priv = glamor_get_pixmap_private(pixmap); - - pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); - - glamor_set_normalize_vcoords(xscale, yscale, - x, y, - x + w, y + h, - glamor_priv->yInverted, dest_coords); - - glamor_fallback("glamor_put_image_xybitmap: disabled\n"); - goto fail; - - if (glamor_priv->put_image_xybitmap_prog == 0) { - ErrorF("no program for xybitmap putimage\n"); - goto fail; - } - - glamor_set_alu(gc->alu); - if (!glamor_set_planemask(pixmap, gc->planemask)) - goto fail; - - glUseProgram(glamor_priv->put_image_xybitmap_prog); - - glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); - glUniform4fv(glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); - glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); - glUniform4fv(glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); - - glGenTextures(1, &tex); - glActiveTexture(GL_TEXTURE0); - 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); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, - w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - - /* Now that we've set up our bitmap texture and the shader, shove - * the destination rectangle through the cliprects and run the - * shader on the resulting fragments. - */ - glVertexPointer(2, GL_FLOAT, 0, dest_coords); - glEnableClientState(GL_VERTEX_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glEnable(GL_SCISSOR_TEST); - clip = fbGetCompositeClip(gc); - for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) { - int x1 = x; - int y1 = y; - int x2 = x + w; - int y2 = y + h; - - if (x1 < box->x1) - x1 = box->x1; - if (y1 < box->y1) - y1 = box->y1; - if (x2 > box->x2) - x2 = box->x2; - if (y2 > box->y2) - y2 = box->y2; - if (x1 >= x2 || y1 >= y2) - continue; - - glScissor(box->x1, y_flip(pixmap, box->y1), - box->x2 - box->x1, box->y2 - box->y1); - glDrawArrays(GL_QUADS, 0, 4); - } - - glDisable(GL_SCISSOR_TEST); - glamor_set_alu(GXcopy); - glamor_set_planemask(pixmap, ~0); - glDeleteTextures(1, &tex); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - return; - glamor_set_alu(GXcopy); - glamor_set_planemask(pixmap, ~0); - glamor_fallback(": to %p (%c)\n", - drawable, glamor_get_drawable_location(drawable)); - fail: - if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) && - glamor_prepare_access_gc(gc)) { - fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); - } - glamor_finish_access_gc(gc); - glamor_finish_access(drawable); -} -#endif - void glamor_fini_putimage_shaders(ScreenPtr screen) { From 9999a660135fafe5f1fdf9452e5ca74ffb069dc2 Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Thu, 13 Mar 2014 11:17:39 +0100 Subject: [PATCH 31/33] glamor: don't reset the GLSL program We don't use fixed function rendering, so there is no need to reset the program at all. This lets the driver avoid checking for state changes between draw calls when we rebind the same program. Improves xephyr x11perf -f8text performance by 6.03062% +/- 1.64928% (n=20) Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- glamor/glamor_copyarea.c | 1 - glamor/glamor_core.c | 2 -- glamor/glamor_fill.c | 1 - glamor/glamor_glyphblt.c | 2 -- glamor/glamor_gradient.c | 8 -------- glamor/glamor_pixmap.c | 2 -- glamor/glamor_render.c | 1 - glamor/glamor_tile.c | 2 -- glamor/glamor_trapezoid.c | 4 ---- glamor/glamor_xv.c | 1 - 10 files changed, 24 deletions(-) diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 0b170dc79..996611c6c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -205,7 +205,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); /* The source texture is bound to a fbo, we have to flush it here. */ glamor_put_context(glamor_priv); glamor_priv->state = RENDER_STATE; diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index 9e07b2b61..6c0b3c834 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -289,7 +289,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUniform1i(sampler_uniform_location, 0); glUniform1i(glamor_priv->finish_access_revert[0], 0); glUniform1i(glamor_priv->finish_access_swap_rb[0], 0); - glUseProgram(0); glamor_priv->finish_access_revert[1] = glGetUniformLocation(glamor_priv->finish_access_prog[1], "revert"); @@ -301,7 +300,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen) glUniform1i(glamor_priv->finish_access_revert[1], 0); glUniform1i(sampler_uniform_location, 0); glUniform1i(glamor_priv->finish_access_swap_rb[1], 0); - glUseProgram(0); glamor_put_context(glamor_priv); } diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c index e58b336df..7461b62fa 100644 --- a/glamor/glamor_fill.c +++ b/glamor/glamor_fill.c @@ -258,7 +258,6 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color) free(vertices); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); glamor_put_context(glamor_priv); glamor_priv->state = RENDER_STATE; glamor_priv->render_idle_cnt = 0; diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c index 5d785a069..a58cef907 100644 --- a/glamor/glamor_glyphblt.c +++ b/glamor/glamor_glyphblt.c @@ -156,7 +156,6 @@ glamor_poly_glyph_blt_pixels(DrawablePtr drawable, GCPtr gc, } glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); glamor_put_context(glamor_priv); @@ -328,7 +327,6 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap, glDrawArrays(GL_POINTS, 0, num_points); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); glamor_put_context(glamor_priv); diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c index 0769eaeaa..f77d6a8e3 100644 --- a/glamor/glamor_gradient.c +++ b/glamor/glamor_gradient.c @@ -379,8 +379,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, glamor_link_glsl_prog(screen, gradient_prog, "radial gradient"); - glUseProgram(0); - if (dyn_gen) { index = 2; glamor_priv->radial_max_nstops = stops_count; @@ -592,8 +590,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, glamor_link_glsl_prog(screen, gradient_prog, "linear gradient"); - glUseProgram(0); - if (dyn_gen) { index = 2; glamor_priv->linear_max_nstops = stops_count; @@ -1169,7 +1165,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); glamor_put_context(glamor_priv); return dst_picture; @@ -1191,7 +1186,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); glamor_put_context(glamor_priv); return NULL; } @@ -1522,7 +1516,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); glamor_put_context(glamor_priv); return dst_picture; @@ -1544,7 +1537,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); glamor_put_context(glamor_priv); return NULL; } diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c index 1c258a2b8..615faad33 100644 --- a/glamor/glamor_pixmap.c +++ b/glamor/glamor_pixmap.c @@ -856,7 +856,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glUseProgram(0); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDeleteTextures(1, &tex); @@ -1181,7 +1180,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); glamor_put_context(glamor_priv); return temp_fbo; } diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c index 2496f8429..c0ee22c2f 100644 --- a/glamor/glamor_render.c +++ b/glamor/glamor_render.c @@ -1335,7 +1335,6 @@ glamor_composite_with_shader(CARD8 op, glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); glDisable(GL_BLEND); DEBUGF("finish rendering.\n"); - glUseProgram(0); glamor_priv->state = RENDER_STATE; glamor_priv->render_idle_cnt = 0; if (saved_source_format) diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c index ba7f11fc7..9e115cad1 100644 --- a/glamor/glamor_tile.c +++ b/glamor/glamor_tile.c @@ -82,7 +82,6 @@ glamor_init_tile_shader(ScreenPtr screen) glamor_priv->tile_wh = glGetUniformLocation(glamor_priv->tile_prog, "wh"); - glUseProgram(0); glamor_put_context(glamor_priv); } @@ -156,7 +155,6 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile, glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); - glUseProgram(0); glamor_put_context(glamor_priv); glamor_priv->state = RENDER_STATE; diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c index 9c39740b6..969ab68bc 100644 --- a/glamor/glamor_trapezoid.c +++ b/glamor/glamor_trapezoid.c @@ -982,7 +982,6 @@ _glamor_trapezoids_with_shader(CARD8 op, glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_MASK); glDisable(GL_BLEND); - glUseProgram(0); glamor_put_context(glamor_priv); TRAPEZOID_OUT: @@ -1359,8 +1358,6 @@ glamor_init_trapezoid_shader(ScreenPtr screen) glamor_link_glsl_prog(screen, glamor_priv->trapezoid_prog, "trapezoid"); - glUseProgram(0); - glamor_put_context(glamor_priv); } @@ -1573,7 +1570,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture, glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM); glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM); glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM); - glUseProgram(0); glamor_put_context(glamor_priv); return TRUE; } diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index c0219b03e..17745a4e8 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -416,7 +416,6 @@ glamor_display_textured_video(glamor_port_private *port_priv) glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); - glUseProgram(0); glamor_put_context(glamor_priv); DamageDamageRegion(port_priv->pDraw, &port_priv->clip); } From b5a61239e2fef167c229154d7919ff862503e3f3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 14 Mar 2014 13:10:04 -0700 Subject: [PATCH 32/33] glx: Make sure we get an FBConfig the root window's visual. Signed-off-by: Eric Anholt Reviewed-by: Keith Packard --- hw/kdrive/ephyr/ephyr_glamor_glx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c index eaf565496..9903cc772 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -313,6 +313,7 @@ ephyr_glamor_get_visual(void) GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, 1, + GLX_VISUAL_ID, DefaultVisual(dpy, DefaultScreen(dpy)), None }; int event_base = 0, error_base = 0, nelements; From 6649d0059e1bc136b84a9e457ae81c07521fadc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 17 Mar 2014 13:16:48 +0900 Subject: [PATCH 33/33] glamor: Move up glamor_priv->flags assignment in glamor_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It wasn't assigned yet when it was tested for GLAMOR_NO_DRI3. Signed-off-by: Michel Dänzer Signed-off-by: Eric Anholt Reviewed-by: Eric Anholt --- glamor/glamor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glamor/glamor.c b/glamor/glamor.c index a624a7bd6..0f7d68b70 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -313,6 +313,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) if (glamor_priv == NULL) return FALSE; + glamor_priv->flags = flags; if (flags & GLAMOR_INVERTED_Y_AXIS) { glamor_priv->yInverted = TRUE; } @@ -487,7 +488,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_pixmap_init(screen); glamor_glyphs_init(screen); - glamor_priv->flags = flags; glamor_priv->screen = screen; return TRUE;