diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 2927e898f..4c51b0155 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -2250,6 +2250,13 @@ clutter_actor_paint (ClutterActor *self) g_return_if_fail (CLUTTER_IS_ACTOR (self)); priv = self->priv; + context = clutter_context_get_default (); + + /* It's an important optimization that we consider painting of + * actors with 0 opacity to be a NOP... */ + if (G_LIKELY (context->pick_mode == CLUTTER_PICK_NONE) && + priv->opacity == 0) + return; /* if we aren't paintable (not in a toplevel with all * parents paintable) then do nothing. @@ -2284,7 +2291,6 @@ clutter_actor_paint (ClutterActor *self) clip_set = TRUE; } - context = clutter_context_get_default (); if (G_UNLIKELY (context->pick_mode != CLUTTER_PICK_NONE)) { ClutterColor col = { 0, }; @@ -4208,6 +4214,9 @@ clutter_actor_destroy (ClutterActor *self) * * This function will not do anything if @self is not visible, or * if the actor is inside an invisible part of the scenegraph. + * + * Also be aware that painting is a NOP for actors with an opacity of + * 0 */ void clutter_actor_queue_redraw (ClutterActor *self) diff --git a/clutter/cogl/cogl.h.in b/clutter/cogl/cogl.h.in index b3b0584b0..bd3698312 100644 --- a/clutter/cogl/cogl.h.in +++ b/clutter/cogl/cogl.h.in @@ -325,9 +325,9 @@ void cogl_enable_depth_test (gboolean setting); * * Sets whether textures positioned so that their backface is showing * should be hidden. This can be used to efficiently draw two-sided - * textures or fully closed cubes without enabling depth testing. Only - * calls to cogl_texture_rectangle() and cogl_texture_polygon() are - * affected. Backface culling is disabled by default. + * textures or fully closed cubes without enabling depth testing. This + * only affects calls to the cogl_rectangle* family of functions and + * cogl_vertex_buffer_draw*. Backface culling is disabled by default. */ void cogl_enable_backface_culling (gboolean setting); diff --git a/clutter/cogl/common/cogl-internal.h b/clutter/cogl/common/cogl-internal.h index f148c35b6..980e2a886 100644 --- a/clutter/cogl/common/cogl-internal.h +++ b/clutter/cogl/common/cogl-internal.h @@ -62,6 +62,7 @@ const gchar *cogl_gl_error_to_string (GLenum error_code); { \ g_warning ("%s: GL error (%d): %s\n", \ G_STRLOC, \ + __err, \ cogl_gl_error_to_string (__err)); \ } } G_STMT_END diff --git a/clutter/cogl/common/cogl-vertex-buffer.c b/clutter/cogl/common/cogl-vertex-buffer.c index b7e004a49..f6fa6ba89 100644 --- a/clutter/cogl/common/cogl-vertex-buffer.c +++ b/clutter/cogl/common/cogl-vertex-buffer.c @@ -1647,6 +1647,9 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material); + if (ctx->enable_backface_culling) + enable_flags |= COGL_ENABLE_BACKFACE_CULLING; + cogl_enable (enable_flags); } @@ -1723,6 +1726,8 @@ cogl_vertex_buffer_draw (CoglHandle handle, if (!cogl_is_vertex_buffer (handle)) return; + cogl_clip_ensure (); + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); enable_state_for_drawing_buffer (buffer); @@ -1751,6 +1756,8 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle, if (!cogl_is_vertex_buffer (handle)) return; + cogl_clip_ensure (); + buffer = _cogl_vertex_buffer_pointer_from_handle (handle); enable_state_for_drawing_buffer (buffer); diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index c2f5aadcc..c1a02206e 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -331,7 +331,10 @@ create_cogl_texture (ClutterTexture *texture, cogl_format = COGL_PIXEL_FORMAT_RGB_888; } else - g_critical ("Can't create a TFP cogl texture for pixmap with depth < 24"); + { + g_critical ("Can't create a TFP cogl texture for pixmap with depth < 24"); + return FALSE; + } /* We want to use the GL_ARB_texture_rectangle extension on some chipsets because GL_ARB_texture_non_power_of_two is not always @@ -345,7 +348,7 @@ create_cogl_texture (ClutterTexture *texture, glGenTextures (1, &tex); glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex); glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0, - GL_RGB, width, height, + gl_format, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); handle = cogl_texture_new_from_foreign (tex, CGL_TEXTURE_RECTANGLE_ARB, diff --git a/configure.ac b/configure.ac index 024fda1d7..9c421a941 100644 --- a/configure.ac +++ b/configure.ac @@ -590,7 +590,7 @@ AC_ARG_ENABLE([cogl-debug], [AC_HELP_STRING([--enable-cogl-debug=@<:@no/yes@:>@], [Turn on COGL debugging])], [], - [enable_debug=debug_default]) + [enable_debug=cogl_debug_default]) AS_CASE([$enable_debug], diff --git a/tests/micro-bench/Makefile.am b/tests/micro-bench/Makefile.am index b20678fb9..4238d0d6f 100644 --- a/tests/micro-bench/Makefile.am +++ b/tests/micro-bench/Makefile.am @@ -1,6 +1,7 @@ noinst_PROGRAMS = \ test-text \ - test-picking + test-picking \ + test-text-perf INCLUDES = -I$(top_srcdir)/ -I$(top_srcdir)/clutter -I$(top_builddir)/clutter LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la @@ -12,4 +13,5 @@ AM_LDFLAGS = $(CLUTTER_LIBS) test_text_SOURCES = test-text.c test_picking_SOURCES = test-picking.c +test_text_perf_SOURCES = test-text-perf.c diff --git a/tests/micro-bench/test-text-perf.c b/tests/micro-bench/test-text-perf.c new file mode 100644 index 000000000..8c7d0c492 --- /dev/null +++ b/tests/micro-bench/test-text-perf.c @@ -0,0 +1,122 @@ +#include + +#include +#include + +#define STAGE_WIDTH 800 +#define STAGE_HEIGHT 600 + +static int font_size; +static int n_chars; +static int rows, cols; + +gboolean idle (gpointer data) +{ + ClutterActor *stage = CLUTTER_ACTOR (data); + + static GTimer *timer = NULL; + static int fps = 0; + + if (!timer) + { + timer = g_timer_new (); + g_timer_start (timer); + } + + if (g_timer_elapsed (timer, NULL) >= 1) + { + printf ("fps=%d, strings/sec=%d, chars/sec=%d\n", + fps, + fps * rows * cols, + fps * rows * cols * n_chars); + g_timer_start (timer); + fps = 0; + } + + clutter_actor_paint (stage); + ++fps; + + return TRUE; +} + +static ClutterActor * +create_label () +{ + ClutterColor label_color = { 0xff, 0xff, 0xff, 0xff }; + ClutterActor *label; + char *font_name; + GString *str; + int i; + + font_name = g_strdup_printf ("Monospace %dpx", font_size); + + str = g_string_new (NULL); + for (i = 0; i < n_chars; i++) + g_string_append_c (str, 'A' + (i % 26)); + + label = clutter_text_new_with_text (font_name, str->str); + clutter_text_set_color (CLUTTER_TEXT (label), &label_color); + + g_free (font_name); + g_string_free (str, TRUE); + + return label; +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage; + ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; + ClutterActor *label; + int w, h; + int row, col; + + g_setenv ("CLUTTER_VBLANK", "none", FALSE); + + clutter_init (&argc, &argv); + + if (argc != 3) + { + g_printerr ("Usage test-text-perf FONT_SIZE N_CHARS\n"); + exit (1); + } + + font_size = atoi (argv[1]); + n_chars = atoi (argv[2]); + + g_print ("Monospace %dpx, string length = %d\n", font_size, n_chars); + + stage = clutter_stage_get_default (); + clutter_actor_set_size (stage, STAGE_WIDTH, STAGE_HEIGHT); + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + + label = create_label (); + w = clutter_actor_get_width (label); + h = clutter_actor_get_height (label); + cols = STAGE_WIDTH / w; + rows = STAGE_HEIGHT / h; + clutter_actor_destroy (label); + + if (cols == 0 || rows == 0) + { + g_printerr("Too many characters to fit in stage\n"); + exit(1); + } + + for (row=0; row