diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index b7762cc22..172b9593c 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -41,22 +41,25 @@ glamor_copy_n_to_n_copypixels(DrawablePtr src, int dx, int dy) { + ScreenPtr screen = dst->pScreen; PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int x_off, y_off, i; if (src != dst) { - glamor_fallback("glamor_copy_n_to_n_copypixels(): src != dest\n"); + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " + "src != dest\n"); return FALSE; } if (gc) { if (gc->alu != GXcopy) { - glamor_fallback("glamor_copy_n_to_n_copypixels(): non-copy ALU\n"); + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " + "non-copy ALU\n"); return FALSE; } if (!glamor_pm_is_solid(dst, gc->planemask)) { - glamor_fallback("glamor_copy_n_to_n_copypixels(): " - "non-solid planemask\n"); + glamor_delayed_fallback(screen, "glamor_copy_n_to_n_copypixels(): " + "non-solid planemask\n"); return FALSE; } } @@ -196,11 +199,17 @@ glamor_copy_n_to_n(DrawablePtr src, Pixel bitplane, void *closure) { - if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) + if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) { + glamor_clear_delayed_fallbacks(dst->pScreen); return; + } - if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) + if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) { + glamor_clear_delayed_fallbacks(dst->pScreen); return; + } + + glamor_report_delayed_fallbacks(dst->pScreen); glamor_fallback("glamor_copy_area() from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 91fa6e1fe..cd7ca1528 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -126,6 +126,8 @@ typedef struct glamor_screen_private { CopyWindowProcPtr saved_copy_window; BitmapToRegionProcPtr saved_bitmap_to_region; + char *delayed_fallback_string; + /* glamor_finishaccess */ GLint finish_access_prog; @@ -196,6 +198,41 @@ glamor_fallback(char *format, ...) va_end(ap); } +static inline void +glamor_delayed_fallback(ScreenPtr screen, char *format, ...) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + va_list ap; + + if (glamor_priv->delayed_fallback_string != NULL) + return; + + va_start(ap, format); + glamor_priv->delayed_fallback_string = XNFvprintf(format, ap); + va_end(ap); +} + +static inline void +glamor_clear_delayed_fallbacks(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + xfree(glamor_priv->delayed_fallback_string); + glamor_priv->delayed_fallback_string = NULL; +} + +static inline void +glamor_report_delayed_fallbacks(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + if (glamor_priv->delayed_fallback_string) { + LogMessageVerb(X_INFO, 0, "fallback: %s", + glamor_priv->delayed_fallback_string); + glamor_clear_delayed_fallbacks(screen); + } +} + static inline float v_from_x_coord_x(PixmapPtr pixmap, int x) {