diff --git a/docs/reference/gtk/running.sgml b/docs/reference/gtk/running.sgml
index 899f765c57..cdb8fb0945 100644
--- a/docs/reference/gtk/running.sgml
+++ b/docs/reference/gtk/running.sgml
@@ -381,6 +381,41 @@ nevertheless.
+
+ GDK_RENDERING
+
+
+ If set, selects the way how GDK creates similar surfaces. This affects both the
+ functionality of the function gdk_window_create_similar_surface() as well as the
+ way GDK creates backing surfaces for double buffering. The following values can
+ be used:
+
+
+
+ similar
+ Create similar surfaces to the window in use. This is the
+ default behavior when the variable is not set.
+
+
+
+ image
+ Always create image surfaces. This essentially turns off
+ all hardware acceleration inside GTK.
+
+
+
+ recording
+ Always create recording surfaces. This causes bare rendering
+ to the backend without the creation of intermediate surfaces (Pixmaps in X)
+ and will likely cause flicker.
+
+
+
+ All other values will be ignored and fall back to the default behavior. More
+ values might be added in the future.
+
+
+
GDK_BACKEND
diff --git a/gdk/gdk.c b/gdk/gdk.c
index 43d45f50d2..16b4e74ca5 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -215,6 +215,8 @@ gdk_add_option_entries_libgtk_only (GOptionGroup *group)
void
gdk_pre_parse_libgtk_only (void)
{
+ const char *rendering_mode;
+
gdk_initialized = TRUE;
/* We set the fallback program class here, rather than lazily in
@@ -241,6 +243,17 @@ gdk_pre_parse_libgtk_only (void)
g_unsetenv ("GDK_NATIVE_WINDOWS");
}
+ rendering_mode = g_getenv ("GDK_RENDERING");
+ if (rendering_mode)
+ {
+ if (g_str_equal (rendering_mode, "similar"))
+ _gdk_rendering_mode = GDK_RENDERING_MODE_SIMILAR;
+ else if (g_str_equal (rendering_mode, "image"))
+ _gdk_rendering_mode = GDK_RENDERING_MODE_IMAGE;
+ else if (g_str_equal (rendering_mode, "recording"))
+ _gdk_rendering_mode = GDK_RENDERING_MODE_RECORDING;
+ }
+
g_type_init ();
/* Do any setup particular to the windowing system */
diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c
index 32a02533fe..a9b642997e 100644
--- a/gdk/gdkglobals.c
+++ b/gdk/gdkglobals.c
@@ -27,14 +27,13 @@
#include "config.h"
#include "gdktypes.h"
-#include "gdkprivate.h"
+#include "gdkinternals.h"
#include
-
guint _gdk_debug_flags = 0;
GList *_gdk_default_filters = NULL;
gchar *_gdk_display_name = NULL;
gchar *_gdk_display_arg_name = NULL;
gboolean _gdk_disable_multidevice = FALSE;
-
+GdkRenderingMode _gdk_rendering_mode = GDK_RENDERING_MODE_SIMILAR;
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 790763b361..4fd8129fa8 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -87,10 +87,17 @@ typedef enum {
GDK_DEBUG_EVENTLOOP = 1 << 10
} GdkDebugFlag;
+typedef enum {
+ GDK_RENDERING_MODE_SIMILAR = 0,
+ GDK_RENDERING_MODE_IMAGE,
+ GDK_RENDERING_MODE_RECORDING
+} GdkRenderingMode;
+
extern GList *_gdk_default_filters;
extern GdkWindow *_gdk_parent_root;
extern guint _gdk_debug_flags;
+extern GdkRenderingMode _gdk_rendering_mode;
#ifdef G_ENABLE_DEBUG
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index e3177f01fb..8a5c87d32d 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -9709,9 +9709,26 @@ gdk_window_create_similar_surface (GdkWindow * window,
window_surface = _gdk_window_ref_cairo_surface (window);
- surface = cairo_surface_create_similar (window_surface,
- content,
- width, height);
+ switch (_gdk_rendering_mode)
+ {
+ case GDK_RENDERING_MODE_RECORDING:
+ {
+ cairo_rectangle_t rect = { 0, 0, width, height };
+ surface = cairo_recording_surface_create (content, &rect);
+ }
+ break;
+ case GDK_RENDERING_MODE_IMAGE:
+ surface = cairo_image_surface_create (content == CAIRO_CONTENT_COLOR ? CAIRO_FORMAT_RGB24 :
+ content == CAIRO_CONTENT_ALPHA ? CAIRO_FORMAT_A8 : CAIRO_FORMAT_ARGB32,
+ width, height);
+ break;
+ case GDK_RENDERING_MODE_SIMILAR:
+ default:
+ surface = cairo_surface_create_similar (window_surface,
+ content,
+ width, height);
+ break;
+ }
cairo_surface_destroy (window_surface);