[Xfce4-commits] [xfce/xfwm4] 03/07: compositor: Optimize GLX code path
noreply at xfce.org
noreply at xfce.org
Wed May 8 09:31:22 CEST 2019
This is an automated email from the git hooks/post-receive script.
o l i v i e r p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository xfce/xfwm4.
commit a818cc065378cad74b8150484c6457e0b2d99e28
Author: Olivier Fourdan <fourdan at xfce.org>
Date: Wed May 8 08:56:08 2019 +0200
compositor: Optimize GLX code path
When not zooming, use the damage region to update the back buffer
instead of copying the entire texture.
Signed-off-by: Olivier Fourdan <fourdan at xfce.org>
---
src/compositor.c | 153 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 94 insertions(+), 59 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index 7ad9ef7..c8b72f8 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1522,17 +1522,62 @@ scale_glx_texture (ScreenInfo *screen_info, gint width, gint height, double zoom
}
static void
-redraw_glx_texture (ScreenInfo *screen_info)
+redraw_glx_rects (ScreenInfo *screen_info, XRectangle *rects, int nrects)
+{
+ int i;
+
+ glBegin(GL_QUADS);
+ for (i = 0; i < nrects; i++)
+ {
+ double texture_x1 = (double) (rects[i].x) / screen_info->width;
+ double texture_y1 = (double) (rects[i].y) / screen_info->height;
+ double texture_x2 = (double) (rects[i].x + rects[i].width) / screen_info->width;
+ double texture_y2 = (double) (rects[i].y + rects[i].height) / screen_info->height;
+ double vertice_x1 = 2 * texture_x1 - 1.0;
+ double vertice_y1 = -2 * texture_y1 + 1.0;
+ double vertice_x2 = 2 * texture_x2 - 1.0;
+ double vertice_y2 = -2 * texture_y2 + 1.0;
+
+ if (screen_info->texture_inverted)
+ {
+ texture_y1 = 1.0 - texture_y1;
+ texture_y2 = texture_y2 - 1.0;
+ }
+
+ TRACE ("Rect#%i: Texture (%.2f,%.2f,%.2f,%.2f) to vertice (%.2f,%.2f,%.2f,%.2f)", i,
+ texture_x1, texture_y1, texture_x2, texture_y2,
+ vertice_x1, vertice_y1, vertice_x2, vertice_y2);
+
+ glTexCoord2f (texture_x1, texture_y1);
+ glVertex2f (vertice_x1, vertice_y1);
+ glTexCoord2f (texture_x2, texture_y1);
+ glVertex2f (vertice_x2, vertice_y1);
+ glTexCoord2f (texture_x2, texture_y2);
+ glVertex2f (vertice_x2, vertice_y2);
+ glTexCoord2f (texture_x1, texture_y2);
+ glVertex2f (vertice_x1, vertice_y2);
+ }
+ glEnd();
+}
+
+static void
+redraw_glx_texture (ScreenInfo *screen_info, XserverRegion region)
{
g_return_if_fail (screen_info != NULL);
TRACE ("(re)Drawing GLX pixmap 0x%lx/texture 0x%x",
screen_info->glx_drawable, screen_info->rootTexture);
+ glReadBuffer (GL_FRONT);
+ glDrawBuffer (GL_BACK);
+ glViewport(0, 0, screen_info->width, screen_info->height);
+
glMatrixMode(GL_TEXTURE);
glPushMatrix();
if (screen_info->zoomed)
{
+ XRectangle root_rect = { 0, 0, screen_info->width, screen_info->height};
+
/* Reuse the values from the XRender matrix */
XFixed zf = screen_info->transform.matrix[0][0];
XFixed xp = screen_info->transform.matrix[0][2];
@@ -1544,24 +1589,23 @@ redraw_glx_texture (ScreenInfo *screen_info)
scale_glx_texture (screen_info, screen_info->width, screen_info->height, zoom);
glTranslated (x, y, 0.0);
+
+ redraw_glx_rects (screen_info, &root_rect, 1);
}
else
{
+ XRectangle bounds;
+ XRectangle *rects;
+ int nrects;
+
scale_glx_texture (screen_info, screen_info->width, screen_info->height, 1.0);
glTranslated (0.0, 0.0, 0.0);
- }
- glViewport(0, 0, screen_info->width, screen_info->height);
- glBegin(GL_QUADS);
- glTexCoord2f(0.0, screen_info->texture_inverted ? 1.0 : 0.0);
- glVertex2f(-1.0, 1.0);
- glTexCoord2f(1.0, screen_info->texture_inverted ? 1.0 : 0.0);
- glVertex2f( 1.0, 1.0);
- glTexCoord2f(1.0, screen_info->texture_inverted ? 0.0 : 1.0);
- glVertex2f( 1.0, -1.0);
- glTexCoord2f(0.0, screen_info->texture_inverted ? 0.0 : 1.0);
- glVertex2f(-1.0, -1.0);
- glEnd();
+ rects = XFixesFetchRegionAndBounds (myScreenGetXDisplay (screen_info),
+ region, &nrects, &bounds);
+ redraw_glx_rects (screen_info, rects, nrects);
+ XFree (rects);
+ }
glPopMatrix();
@@ -1999,14 +2043,14 @@ paint_win (CWindow *cw, XserverRegion region, Picture paint_buffer, gboolean sol
static gboolean
is_region_empty (Display *dpy, XserverRegion region)
{
- XRectangle bounds;
- XRectangle *rects;
- int nrects;
+ XRectangle bounds;
+ XRectangle *rects;
+ int nrects;
- rects = XFixesFetchRegionAndBounds (dpy, region, &nrects, &bounds);
- XFree (rects);
+ rects = XFixesFetchRegionAndBounds (dpy, region, &nrects, &bounds);
+ XFree (rects);
- return (nrects == 0 || bounds.width == 0 || bounds.height == 0);
+ return (nrects == 0 || bounds.width == 0 || bounds.height == 0);
}
static void
@@ -2240,7 +2284,7 @@ paint_all (ScreenInfo *screen_info, XserverRegion region, gushort buffer)
screen_info->rootPixmap[buffer]);
bind_glx_texture (screen_info,
screen_info->rootPixmap[buffer]);
- redraw_glx_texture (screen_info);
+ redraw_glx_texture (screen_info, region);
}
else
#endif /* HAVE_EPOXY */
@@ -2280,6 +2324,7 @@ static gboolean
repair_screen (ScreenInfo *screen_info)
{
DisplayInfo *display_info;
+ XserverRegion damage;
g_return_val_if_fail (screen_info, FALSE);
TRACE ("entering");
@@ -2290,56 +2335,46 @@ repair_screen (ScreenInfo *screen_info)
}
display_info = screen_info->display_info;
- if (screen_info->allDamage)
+ damage = screen_info->allDamage;
+ if (damage)
{
#ifdef HAVE_PRESENT_EXTENSION
- if (screen_info->use_present)
+ if (screen_info->use_present && screen_info->present_pending)
{
- if (!screen_info->present_pending)
- {
- XserverRegion damage = screen_info->allDamage;
-
- if (screen_info->prevDamage)
- {
- XFixesUnionRegion(display_info->dpy,
- screen_info->prevDamage,
- screen_info->prevDamage,
- damage);
- damage = screen_info->prevDamage;
- }
-
- remove_timeouts (screen_info);
- paint_all (screen_info, damage, screen_info->current_buffer);
-
- if (++screen_info->current_buffer > 1)
- {
- screen_info->current_buffer = 0;
- }
-
- if (screen_info->prevDamage)
- {
- XFixesDestroyRegion (display_info->dpy, screen_info->prevDamage);
- }
-
- screen_info->prevDamage = screen_info->allDamage;
- screen_info->allDamage = None;
-
- return FALSE;
- }
/*
- * We did not paint the screen because we are waiting for
+ * We do not paint the screen because we are waiting for
* a pending present notification, do not cancel the callback yet...
*/
return TRUE;
}
- else
#endif /* HAVE_PRESENT_EXTENSION */
+
+ if (screen_info->prevDamage)
{
- remove_timeouts (screen_info);
- paint_all (screen_info, screen_info->allDamage, screen_info->current_buffer);
- XFixesDestroyRegion (display_info->dpy, screen_info->allDamage);
- screen_info->allDamage = None;
+ XFixesUnionRegion(display_info->dpy,
+ screen_info->prevDamage,
+ screen_info->prevDamage,
+ damage);
+ damage = screen_info->prevDamage;
}
+
+ remove_timeouts (screen_info);
+ paint_all (screen_info, damage, screen_info->current_buffer);
+
+ if (screen_info->prevDamage)
+ {
+ XFixesDestroyRegion (display_info->dpy, screen_info->prevDamage);
+ }
+
+ screen_info->prevDamage = screen_info->allDamage;
+ screen_info->allDamage = None;
+
+#ifdef HAVE_PRESENT_EXTENSION
+ if (screen_info->use_present)
+ {
+ screen_info->current_buffer = (screen_info->current_buffer + 1) % 2;
+ }
+#endif /* HAVE_PRESENT_EXTENSION */
}
return FALSE;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list