]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Agglomerate more mallocs to speed-up gfxterm.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 4 May 2013 20:23:23 +0000 (22:23 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sat, 4 May 2013 20:23:23 +0000 (22:23 +0200)
15 files changed:
ChangeLog
grub-core/font/font.c
grub-core/gfxmenu/font.c
grub-core/gfxmenu/gui_list.c
grub-core/gfxmenu/gui_progress_bar.c
grub-core/kern/term.c
grub-core/normal/charset.c
grub-core/normal/menu_entry.c
grub-core/normal/menu_text.c
grub-core/normal/term.c
grub-core/term/gfxterm.c
grub-core/tests/video_checksum.c
grub-core/video/fb/fbblit.c
include/grub/emu/export.h
include/grub/unicode.h

index 963792e32d3575bacd68b122fab59cf8e6431c4c..57bce500814b8bb29cbea24e43598414c109d551 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Agglomerate more mallocs to speed-up gfxterm.
+
 2013-05-04  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Speed-up gfxterm by slightly agglomerating mallocs.
index 4758f6c0a3df70235c3c6628a33822f510aa0161..50b1799b16f85c123b125e733a79e61d2807077a 100644 (file)
@@ -1064,6 +1064,7 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
   return best_glyph;
 }
 
+#if 0
 static struct grub_font_glyph *
 grub_font_dup_glyph (struct grub_font_glyph *glyph)
 {
@@ -1075,6 +1076,7 @@ grub_font_dup_glyph (struct grub_font_glyph *glyph)
               + (glyph->width * glyph->height + 7) / 8);
   return ret;
 }
+#endif
 
 /* FIXME: suboptimal.  */
 static void
@@ -1202,6 +1204,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
   signed above_leftx, above_lefty;
   signed below_rightx, below_righty;
   signed min_devwidth = 0;
+  const struct grub_unicode_combining *comb;
 
   if (glyph)
     glyph->device_width = main_glyph->device_width;
@@ -1222,6 +1225,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
   below_rightx = ctx.bounds.x + ctx.bounds.width;
   below_righty = ctx.bounds.y;
 
+  comb = grub_unicode_get_comb (glyph_id);
+
   for (i = 0; i < glyph_id->ncomb; i++)
     {
       grub_int16_t space = 0;
@@ -1232,10 +1237,10 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
        continue;
       targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
       /* CGJ is to avoid diacritics reordering. */
-      if (glyph_id->combining[i].code
+      if (comb[i].code
          == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
        continue;
-      switch (glyph_id->combining[i].type)
+      switch (comb[i].type)
        {
        case GRUB_UNICODE_COMB_OVERLAY:
          do_blit (combining_glyphs[i],
@@ -1361,7 +1366,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
          break;
 
        case GRUB_UNICODE_COMB_MN:
-         switch (glyph_id->combining[i].code)
+         switch (comb[i].code)
            {
            case GRUB_UNICODE_THAANA_ABAFILI:
            case GRUB_UNICODE_THAANA_AABAAFILI:
@@ -1410,17 +1415,14 @@ static struct grub_font_glyph *
 grub_font_construct_dry_run (grub_font_t hinted_font,
                             const struct grub_unicode_glyph *glyph_id,
                             struct grub_video_signed_rect *bounds,
-                            struct grub_font_glyph ***combining_glyphs_out,
+                            struct grub_font_glyph **combining_glyphs,
                             int *device_width)
 {
   struct grub_font_glyph *main_glyph = NULL;
-  struct grub_font_glyph **combining_glyphs;
   grub_uint32_t desired_attributes = 0;
   unsigned i;
   grub_uint32_t base = glyph_id->base;
-
-  if (combining_glyphs_out)
-    *combining_glyphs_out = NULL;
+  const struct grub_unicode_combining *comb;
 
   if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED)
     desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED;
@@ -1428,11 +1430,12 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
   if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)
     desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED;
 
+  comb = grub_unicode_get_comb (glyph_id);
 
   if (base == 'i' || base == 'j')
     {
       for (i = 0; i < glyph_id->ncomb; i++)
-       if (glyph_id->combining[i].type == GRUB_UNICODE_STACK_ABOVE)
+       if (comb[i].type == GRUB_UNICODE_STACK_ABOVE)
          break;
       if (i < glyph_id->ncomb && base == 'i')
        base = GRUB_UNICODE_DOTLESS_LOWERCASE_I;
@@ -1461,8 +1464,6 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
   if (!glyph_id->ncomb && !glyph_id->attributes)
     return main_glyph;
 
-  combining_glyphs = grub_malloc (sizeof (combining_glyphs[0])
-                                 * glyph_id->ncomb);
   if (glyph_id->ncomb && !combining_glyphs)
     {
       grub_errno = GRUB_ERR_NONE;
@@ -1472,18 +1473,33 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
   for (i = 0; i < glyph_id->ncomb; i++)
     combining_glyphs[i]
       = grub_font_get_glyph_with_fallback (main_glyph->font,
-                                          glyph_id->combining[i].code);
+                                          comb[i].code);
 
   blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
             device_width);
-  if (combining_glyphs_out)
-    *combining_glyphs_out = combining_glyphs;
-  else
-    grub_free (combining_glyphs);
 
   return main_glyph;
 }
 
+static struct grub_font_glyph **render_combining_glyphs = 0;
+static grub_size_t render_max_comb_glyphs = 0;
+
+static void
+ensure_comb_space (const struct grub_unicode_glyph *glyph_id)
+{
+  if (glyph_id->ncomb <= render_max_comb_glyphs)
+    return;
+
+  render_max_comb_glyphs = 2 * glyph_id->ncomb;
+  if (render_max_comb_glyphs < 8)
+    render_max_comb_glyphs = 8;
+  grub_free (render_combining_glyphs);
+  render_combining_glyphs = grub_malloc (render_max_comb_glyphs
+                                        * sizeof (render_combining_glyphs[0]));
+  if (!render_combining_glyphs)
+    grub_errno = 0;
+}
+
 int
 grub_font_get_constructed_device_width (grub_font_t hinted_font,
                                        const struct grub_unicode_glyph
@@ -1491,8 +1507,11 @@ grub_font_get_constructed_device_width (grub_font_t hinted_font,
 {
   int ret;
   struct grub_font_glyph *main_glyph;
+
+  ensure_comb_space (glyph_id);
+
   main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL,
-                                           NULL, &ret);
+                                           render_combining_glyphs, &ret);
   if (!main_glyph)
     return unknown_glyph->device_width;
   return ret;
@@ -1504,26 +1523,42 @@ grub_font_construct_glyph (grub_font_t hinted_font,
 {
   struct grub_font_glyph *main_glyph;
   struct grub_video_signed_rect bounds;
-  struct grub_font_glyph *glyph;
-  struct grub_font_glyph **combining_glyphs;
+  static struct grub_font_glyph *glyph = 0;
+  static grub_size_t max_glyph_size = 0;
+
+  ensure_comb_space (glyph_id);
 
   main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
-                                           &bounds, &combining_glyphs, NULL);
+                                           &bounds, render_combining_glyphs,
+                                           NULL);
 
   if (!main_glyph)
-    return grub_font_dup_glyph (unknown_glyph);
+    return unknown_glyph;
 
-  if (!combining_glyphs)
-    return grub_font_dup_glyph (main_glyph);
+  if (!render_combining_glyphs && glyph_id->ncomb)
+    return main_glyph;
+
+  if (!glyph_id->ncomb && !glyph_id->attributes)
+    return main_glyph;
 
-  glyph =
-    grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8);
+  if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
+    {
+      grub_free (glyph);
+      max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
+      if (max_glyph_size < 8)
+       max_glyph_size = 8;
+      glyph = grub_malloc (max_glyph_size);
+    }
   if (!glyph)
     {
       grub_errno = GRUB_ERR_NONE;
-      return grub_font_dup_glyph (main_glyph);
+      return main_glyph;
     }
 
+  grub_memset (glyph, 0, sizeof (*glyph)
+              + (bounds.width * bounds.height
+                 + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);
+
   glyph->font = main_glyph->font;
   glyph->width = bounds.width;
   glyph->height = bounds.height;
@@ -1542,9 +1577,7 @@ grub_font_construct_glyph (grub_font_t hinted_font,
                          (glyph->height + glyph->offset_y)
                          - (main_glyph->height + main_glyph->offset_y));
 
-  blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL);
-
-  grub_free (combining_glyphs);
+  blit_comb (glyph_id, glyph, NULL, main_glyph, render_combining_glyphs, NULL);
 
   return glyph;
 }
index 9c6e2d4914644c5f51270ac72c3278e5dc890225..64d52670bfbcddc9e1f5dafeeba6981afab98455 100644 (file)
@@ -42,7 +42,6 @@ grub_font_draw_string (const char *str, grub_font_t font,
                        int left_x, int baseline_y)
 {
   int x;
-  struct grub_font_glyph *glyph;
   grub_uint32_t *logical;
   grub_ssize_t logical_len, visual_len;
   struct grub_unicode_glyph *visual, *ptr;
@@ -60,18 +59,18 @@ grub_font_draw_string (const char *str, grub_font_t font,
   for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
     {
       grub_err_t err;
+      struct grub_font_glyph *glyph;
       glyph = grub_font_construct_glyph (font, ptr);
       if (!glyph)
        return grub_errno;
       err = grub_font_draw_glyph (glyph, color, x, baseline_y);
       x += glyph->device_width;
-      grub_free (glyph);
       if (err)
        return err;
     }
 
   for (ptr = visual; ptr < visual + visual_len; ptr++)
-    grub_free (ptr->combining);
+    grub_unicode_destroy_glyph (ptr);
   grub_free (visual);
 
   return GRUB_ERR_NONE;
@@ -104,7 +103,7 @@ grub_font_get_string_width (grub_font_t font, const char *str)
                                           &glyph);
       width += grub_font_get_constructed_device_width (font, &glyph);
 
-      grub_free (glyph.combining);
+      grub_unicode_destroy_glyph (&glyph);
     }
   grub_free (logical);
 
index 1a2a16d324a1fb79e538565f41d3d00a359e2a8f..3d227eec41f3ff7984397b418a2c5ecd55bbeb1a 100644 (file)
@@ -87,6 +87,7 @@ list_destroy (void *vself)
     self->scrollbar_thumb->destroy (self->scrollbar_thumb);
   if (self->scrollbar_frame)
     self->scrollbar_frame->destroy (self->scrollbar_frame);
+  grub_free (self->scrollbar_thumb_pattern);
   grub_free (self);
 }
 
index cb709302bf24594292ade5d955ee22590e925bf7..b29efc016b2c297612efe39613d965be16a9a804 100644 (file)
@@ -59,6 +59,9 @@ static void
 progress_bar_destroy (void *vself)
 {
   grub_gui_progress_bar_t self = vself;
+  grub_free (self->theme_dir);
+  grub_free (self->template);
+  grub_free (self->id);
   grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
   grub_free (self);
 }
index 66c597130a76c1688b860c20e1471bca7c6e6f8b..6eca68b72d8086a6f239a0f958d98167fe31c94d 100644 (file)
@@ -46,7 +46,6 @@ grub_putcode_dumb (grub_uint32_t code,
       .variant = 0,
       .attributes = 0,
       .ncomb = 0,
-      .combining = 0,
       .estimated_width = 1
     };
 
index ab3101b00327701176cbd4388a4ee53b6da4c371..f4268ec02fad28911741c876599e5b97ce4ac2b3 100644 (file)
@@ -435,7 +435,6 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
       out->attributes = 0;
       out->ncomb = 0;
       out->estimated_width = 1;
-      out->combining = NULL;
       return 1;
     }
 
@@ -473,25 +472,42 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
              || comb_type == GRUB_UNICODE_COMB_ME
              || comb_type == GRUB_UNICODE_COMB_MN)
            last_comb_pointer = out->ncomb;
-         n = grub_realloc (out->combining,
-                           sizeof (n[0]) * (out->ncomb + 1));
-         if (!n)
+
+         if (out->ncomb + 1 <= (int) ARRAY_SIZE (out->combining_inline))
+           n = out->combining_inline;
+         else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
            {
-             grub_errno = GRUB_ERR_NONE;
-             continue;
+             n = grub_realloc (out->combining_ptr,
+                               sizeof (n[0]) * (out->ncomb + 1));
+             if (!n)
+               {
+                 grub_errno = GRUB_ERR_NONE;
+                 continue;
+               }
+             out->combining_ptr = n;
+           }
+         else
+           {
+             n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1));
+             if (!n)
+               {
+                 grub_errno = GRUB_ERR_NONE;
+                 continue;
+               }
+             grub_memcpy (n, out->combining_inline,
+                          sizeof (out->combining_inline));
+             out->combining_ptr = n;
            }
-         out->combining = n;
 
          for (j = last_comb_pointer; j < out->ncomb; j++)
-           if (is_type_after (out->combining[j].type, comb_type))
+           if (is_type_after (n[j].type, comb_type))
              break;
-         grub_memmove (out->combining + j + 1,
-                       out->combining + j,
+         grub_memmove (n + j + 1,
+                       n + j,
                        (out->ncomb - j)
-                       * sizeof (out->combining[0]));
-         out->combining = n;
-         out->combining[j].code = *ptr;
-         out->combining[j].type = comb_type;
+                       * sizeof (n[0]));
+         n[j].code = *ptr;
+         n[j].type = comb_type;
          out->ncomb++;
          continue;
        }
@@ -503,7 +519,6 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
       out->attributes = 0;
       out->ncomb = 0;
       out->estimated_width = 1;
-      out->combining = NULL;
     }
   return ptr - in;
 }
@@ -511,7 +526,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
 static grub_ssize_t
 bidi_line_wrap (struct grub_unicode_glyph *visual_out,
                struct grub_unicode_glyph *visual,
-               grub_size_t visual_len, unsigned *levels,
+               grub_size_t visual_len,
                grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg),
                void *getcharwidth_arg,
                grub_size_t maxwidth, grub_size_t startwidth,
@@ -531,7 +546,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
   void revert (unsigned start, unsigned end)
   {
     struct grub_unicode_glyph t;
-    unsigned i, tl;
+    unsigned i;
     int a, b;
     if (pos)
       {
@@ -549,9 +564,6 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
            pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x;
            pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x;
          }
-       tl = levels[start + i];
-       levels[start + i] = levels[end - i];
-       levels[end - i] = tl;
       }
   }
 
@@ -611,10 +623,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
            unsigned i;
            for (i = line_start; i < k; i++)
              {
-               if (levels[i] > max_level)
-                 max_level = levels[i];
-               if (levels[i] < min_odd_level && (levels[i] & 1))
-                 min_odd_level = levels[i];
+               if (visual[i].bidi_level > max_level)
+                 max_level = visual[i].bidi_level;
+               if (visual[i].bidi_level < min_odd_level && (visual[i].bidi_level & 1))
+                 min_odd_level = visual[i].bidi_level;
              }
          }
 
@@ -627,9 +639,11 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
                unsigned i;
                for (i = line_start; i < k; i++)
                  {
-                   if (i != line_start && levels[i] >= j && levels[i-1] < j)
+                   if (i != line_start && visual[i].bidi_level >= j
+                       && visual[i-1].bidi_level < j)
                      in = i;
-                   if (levels[i] >= j && (i + 1 == k || levels[i+1] < j))
+                   if (visual[i].bidi_level >= j && (i + 1 == k
+                                                || visual[i+1].bidi_level < j))
                      revert (in, i);
                  }
              }
@@ -639,10 +653,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
            unsigned i;
            for (i = line_start; i < k; i++)
              {
-               if (is_mirrored (visual[i].base) && levels[i])
+               if (is_mirrored (visual[i].base) && visual[i].bidi_level)
                  visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR;
                if ((visual[i].attributes & GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN)
-                   && levels[i])
+                   && visual[i].bidi_level)
                  {
                    int left, right;
                    left = visual[i].attributes
@@ -763,8 +777,6 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
 {
   enum grub_bidi_type type = GRUB_BIDI_TYPE_L;
   enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L};
-  unsigned *levels;
-  enum grub_bidi_type *resolved_types;
   unsigned base_level;
   enum override_status cur_override;
   unsigned i;
@@ -808,24 +820,9 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
     cur_override = stack_override[stack_depth];
   }
 
-  levels = grub_malloc (sizeof (levels[0]) * logical_len);
-  if (!levels)
-    return -1;
-
-  resolved_types = grub_malloc (sizeof (resolved_types[0]) * logical_len);
-  if (!resolved_types)
-    {
-      grub_free (levels);
-      return -1;
-    }
-
   visual = grub_malloc (sizeof (visual[0]) * logical_len);
   if (!visual)
-    {
-      grub_free (resolved_types);
-      grub_free (levels);
-      return -1;
-    }
+    return -1;
 
   for (i = 0; i < logical_len; i++)
     {
@@ -930,13 +927,13 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
              join_state = JOIN_DEFAULT;
              zwj_propagate_to_previous = 1;
 
-             levels[visual_len] = cur_level;
+             visual[visual_len].bidi_level = cur_level;
              if (cur_override != OVERRIDE_NEUTRAL)
-               resolved_types[visual_len] = 
+               visual[visual_len].bidi_type = 
                  (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L
                  : GRUB_BIDI_TYPE_R;
              else
-               resolved_types[visual_len] = type;
+               visual[visual_len].bidi_type = type;
              visual_len++;
            }
          }
@@ -951,16 +948,16 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
          unsigned prev_level, next_level, cur_run_level;
          unsigned last_type, last_strong_type;
          for (run_end = run_start; run_end < visual_len &&
-                levels[run_end] == levels[run_start]; run_end++);
+                visual[run_end].bidi_level == visual[run_start].bidi_level; run_end++);
          if (run_start == 0)
            prev_level = base_level;
          else
-           prev_level = levels[run_start - 1];
+           prev_level = visual[run_start - 1].bidi_level;
          if (run_end == visual_len)
            next_level = base_level;
          else
-           next_level = levels[run_end];
-         cur_run_level = levels[run_start];
+           next_level = visual[run_end].bidi_level;
+         cur_run_level = visual[run_start].bidi_level;
          if (prev_level & 1)
            last_type = GRUB_BIDI_TYPE_R;
          else
@@ -968,48 +965,48 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
          last_strong_type = last_type;
          for (i = run_start; i < run_end; i++)
            {
-             switch (resolved_types[i])
+             switch (visual[i].bidi_type)
                {
                case GRUB_BIDI_TYPE_NSM:
-                 resolved_types[i] = last_type;
+                 visual[i].bidi_type = last_type;
                  break;
                case GRUB_BIDI_TYPE_EN:
                  if (last_strong_type == GRUB_BIDI_TYPE_AL)
-                   resolved_types[i] = GRUB_BIDI_TYPE_AN;
+                   visual[i].bidi_type = GRUB_BIDI_TYPE_AN;
                  break;
                case GRUB_BIDI_TYPE_L:
                case GRUB_BIDI_TYPE_R:
-                 last_strong_type = resolved_types[i];
+                 last_strong_type = visual[i].bidi_type;
                  break;
                case GRUB_BIDI_TYPE_ES:
                  if (last_type == GRUB_BIDI_TYPE_EN
                      && i + 1 < run_end 
-                     && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN)
-                   resolved_types[i] = GRUB_BIDI_TYPE_EN;
+                     && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN)
+                   visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
                  else
-                   resolved_types[i] = GRUB_BIDI_TYPE_ON;
+                   visual[i].bidi_type = GRUB_BIDI_TYPE_ON;
                  break;
                case GRUB_BIDI_TYPE_ET:
                  {
                    unsigned j;
                    if (last_type == GRUB_BIDI_TYPE_EN)
                      {
-                       resolved_types[i] = GRUB_BIDI_TYPE_EN;
+                       visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
                        break;
                      }
                    for (j = i; j < run_end
-                          && resolved_types[j] == GRUB_BIDI_TYPE_ET; j++);
-                   if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN)
+                          && visual[j].bidi_type == GRUB_BIDI_TYPE_ET; j++);
+                   if (j != run_end && visual[j].bidi_type == GRUB_BIDI_TYPE_EN)
                      {
                        for (; i < run_end
-                              && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++)
-                         resolved_types[i] = GRUB_BIDI_TYPE_EN;
+                              && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++)
+                         visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
                        i--;
                        break;
                      }
                    for (; i < run_end
-                          && resolved_types[i] == GRUB_BIDI_TYPE_ET; i++)
-                     resolved_types[i] = GRUB_BIDI_TYPE_ON;
+                          && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++)
+                     visual[i].bidi_type = GRUB_BIDI_TYPE_ON;
                    i--;
                    break;              
                  }
@@ -1017,33 +1014,33 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
                case GRUB_BIDI_TYPE_CS:
                  if (last_type == GRUB_BIDI_TYPE_EN
                      && i + 1 < run_end 
-                     && resolved_types[i + 1] == GRUB_BIDI_TYPE_EN)
+                     && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN)
                    {
-                     resolved_types[i] = GRUB_BIDI_TYPE_EN;
+                     visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
                      break;
                    }
                  if (last_type == GRUB_BIDI_TYPE_AN
                      && i + 1 < run_end 
-                     && (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN
-                         || (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN
+                     && (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_AN
+                         || (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN
                              && last_strong_type == GRUB_BIDI_TYPE_AL)))
                    {
-                     resolved_types[i] = GRUB_BIDI_TYPE_EN;
+                     visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
                      break;
                    }
-                 resolved_types[i] = GRUB_BIDI_TYPE_ON;
+                 visual[i].bidi_type = GRUB_BIDI_TYPE_ON;
                  break;
                case GRUB_BIDI_TYPE_AL:
-                 last_strong_type = resolved_types[i];
-                 resolved_types[i] = GRUB_BIDI_TYPE_R;
+                 last_strong_type = visual[i].bidi_type;
+                 visual[i].bidi_type = GRUB_BIDI_TYPE_R;
                  break;
                default: /* Make GCC happy.  */
                  break;
                }
-             last_type = resolved_types[i];
-             if (resolved_types[i] == GRUB_BIDI_TYPE_EN
+             last_type = visual[i].bidi_type;
+             if (visual[i].bidi_type == GRUB_BIDI_TYPE_EN
                  && last_strong_type == GRUB_BIDI_TYPE_L)
-               resolved_types[i] = GRUB_BIDI_TYPE_L;
+               visual[i].bidi_type = GRUB_BIDI_TYPE_L;
            }
          if (prev_level & 1)
            last_type = GRUB_BIDI_TYPE_R;
@@ -1054,13 +1051,13 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
              unsigned j;
              unsigned next_type;
              for (j = i; j < run_end &&
-                    (resolved_types[j] == GRUB_BIDI_TYPE_B
-                     || resolved_types[j] == GRUB_BIDI_TYPE_S
-                     || resolved_types[j] == GRUB_BIDI_TYPE_WS
-                     || resolved_types[j] == GRUB_BIDI_TYPE_ON); j++);
+                    (visual[j].bidi_type == GRUB_BIDI_TYPE_B
+                     || visual[j].bidi_type == GRUB_BIDI_TYPE_S
+                     || visual[j].bidi_type == GRUB_BIDI_TYPE_WS
+                     || visual[j].bidi_type == GRUB_BIDI_TYPE_ON); j++);
              if (j == i)
                {
-                 if (resolved_types[i] == GRUB_BIDI_TYPE_L)
+                 if (visual[i].bidi_type == GRUB_BIDI_TYPE_L)
                    last_type = GRUB_BIDI_TYPE_L;
                  else
                    last_type = GRUB_BIDI_TYPE_R;
@@ -1071,39 +1068,39 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
                next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L;
              else
                {
-                 if (resolved_types[j] == GRUB_BIDI_TYPE_L)
+                 if (visual[j].bidi_type == GRUB_BIDI_TYPE_L)
                    next_type = GRUB_BIDI_TYPE_L;
                  else
                    next_type = GRUB_BIDI_TYPE_R;
                }
              if (next_type == last_type)
                for (; i < j; i++)
-                 resolved_types[i] = last_type;
+                 visual[i].bidi_type = last_type;
              else
                for (; i < j; i++)
-                 resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R
+                 visual[i].bidi_type = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R
                    : GRUB_BIDI_TYPE_L;
            }
        }
 
       for (i = 0; i < visual_len; i++)
        {
-         if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R)
+         if (!(visual[i].bidi_level & 1) && visual[i].bidi_type == GRUB_BIDI_TYPE_R)
            {
-             levels[i]++;
+             visual[i].bidi_level++;
              continue;
            }
-         if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN
-                                  || resolved_types[i] == GRUB_BIDI_TYPE_EN))
+         if (!(visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_AN
+                                  || visual[i].bidi_type == GRUB_BIDI_TYPE_EN))
            {
-             levels[i] += 2;
+             visual[i].bidi_level += 2;
              continue;
            }
-         if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L
-                                 || resolved_types[i] == GRUB_BIDI_TYPE_AN
-                                 || resolved_types[i] == GRUB_BIDI_TYPE_EN))
+         if ((visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_L
+                                 || visual[i].bidi_type == GRUB_BIDI_TYPE_AN
+                                 || visual[i].bidi_type == GRUB_BIDI_TYPE_EN))
            {
-             levels[i]++;
+             visual[i].bidi_level++;
              continue;
            }
        }
@@ -1111,16 +1108,14 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
   else
     {
       for (i = 0; i < visual_len; i++)
-       levels[i] = 0;
+       visual[i].bidi_level = 0;
     }
-  grub_free (resolved_types);
 
   {
     grub_ssize_t ret;
-    ret = bidi_line_wrap (visual_out, visual, visual_len, levels, 
+    ret = bidi_line_wrap (visual_out, visual, visual_len,
                          getcharwidth, getcharwidth_arg, maxwidth, startwidth, contchar,
                          pos, primitive_wrap, log_end);
-    grub_free (levels);
     grub_free (visual);
     return ret;
   }
index 3cc0c0113af746d95c4fe60087070811608beecf..fae258a3fb0d1945e251f07f22237629d755dfb6 100644 (file)
@@ -624,7 +624,7 @@ backward_char (struct screen *screen, int update)
                                                    linep->buf + screen->column)
        - linep->buf;
 
-      grub_free (glyph.combining);
+      grub_unicode_destroy_glyph (&glyph);
     }
   else if (screen->line > 0)
     {
index d7e5641583df7b7a402c6b5e64b4c3fa4efda67f..36f8e738ca2eef9fcc53b09fa81eade1964bcb18 100644 (file)
@@ -56,10 +56,10 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
   while (str < last_position)
     {
       struct grub_unicode_glyph glyph;
-      glyph.combining = 0;
+      glyph.ncomb = 0;
       str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph);
       width += grub_term_getcharwidth (term, &glyph);
-      grub_free (glyph.combining);
+      grub_unicode_destroy_glyph (&glyph);
     }
   return width;
 }
@@ -259,7 +259,8 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
                                             len - i, &glyph);
 
          width = grub_term_getcharwidth (term, &glyph);
-         grub_free (glyph.combining);
+
+         grub_unicode_destroy_glyph (&glyph);
 
          if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X 
                                 + grub_term_border_width (term)
@@ -284,7 +285,6 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
        .variant = 0,
        .attributes = 0,
        .ncomb = 0,
-       .combining = 0,
        .estimated_width = 1
       };
       x += grub_term_getcharwidth (term, &pseudo_glyph);
index 820156f4826765ab872656f1596a4141d9b0a8ca..83b3bcef0c153ba6100d1d972220e8e6b2965e96 100644 (file)
@@ -29,7 +29,7 @@
 struct term_state
 {
   struct term_state *next;
-  const struct grub_unicode_glyph *backlog_glyphs;
+  struct grub_unicode_glyph *backlog_glyphs;
   const grub_uint32_t *backlog_ucs4;
   int backlog_fixed_tab;
   grub_size_t backlog_len;
@@ -228,7 +228,6 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
              .variant = 0,
              .attributes = 0,
              .ncomb = 0,
-             .combining = 0,
              .estimated_width = 1,
              .base = *str
            };
@@ -422,7 +421,6 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term,
       .variant = 0,
       .attributes = 0,
       .ncomb = 0,
-      .combining = 0,
       .estimated_width = 1
     };
 
@@ -475,7 +473,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term,
                }
            }
          else
-           code = c->combining[i].code;
+           code = grub_unicode_get_comb (c) [i].code;
 
          grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8));
 
@@ -506,7 +504,6 @@ putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab)
       .variant = 0,
       .attributes = 0,
       .ncomb = 0,
-      .combining = 0,
       .estimated_width = 1
     };
 
@@ -534,7 +531,6 @@ get_maxwidth (struct grub_term_output *term,
     .variant = 0,
     .attributes = 0,
     .ncomb = 0,
-    .combining = 0
   };
   return (grub_term_width (term)
          - grub_term_getcharwidth (term, &space_glyph) 
@@ -615,7 +611,6 @@ print_ucs4_terminal (const grub_uint32_t * str,
            .variant = 0,
            .attributes = 0,
            .ncomb = 0,
-           .combining = 0
          };
          c.base = *ptr;
          if (pos)
@@ -779,14 +774,14 @@ find_term_state (struct grub_term_output *term)
 }
 
 static int
-put_glyphs_terminal (const struct grub_unicode_glyph *visual,
+put_glyphs_terminal (struct grub_unicode_glyph *visual,
                     grub_ssize_t visual_len,
                     int margin_left, int margin_right,
                     struct grub_term_output *term,
                     struct term_state *state, int fixed_tab,
                     grub_uint32_t contchar)
 {
-  const struct grub_unicode_glyph *visual_ptr;
+  struct grub_unicode_glyph *visual_ptr;
   int since_last_nl = 1;
   for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
     {
@@ -813,7 +808,7 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual,
            grub_term_gotoxy (term, margin_left,
                              grub_term_getxy (term) & 0xff);
        }
-      grub_free (visual_ptr->combining);
+      grub_unicode_destroy_glyph (visual_ptr);
     }
   if (contchar && since_last_nl)
        fill_margin (term, margin_right);
@@ -953,7 +948,7 @@ print_ucs4_real (const grub_uint32_t * str,
          if (visual_len_show && visual[visual_len_show - 1].base != '\n')
            ret++;
          for (vptr = visual; vptr < visual + visual_len; vptr++)
-           grub_free (vptr->combining);
+           grub_unicode_destroy_glyph (vptr);
          grub_free (visual);
        }
       else
@@ -1030,7 +1025,6 @@ grub_xnputs (const char *str, grub_size_t msg_len)
              .variant = 0,
              .attributes = 0,
              .ncomb = 0,
-             .combining = 0,
              .estimated_width = 1,
              .base = *str
            };
index 0cb4037dcd26f7c39a8c60b0513b7098db4dadf3..0e5bcd95f7cdfb5ab5222c81ae8026aef0abf9ae 100644 (file)
@@ -175,7 +175,7 @@ set_term_color (grub_uint8_t term_color)
 static void
 clear_char (struct grub_colored_char *c)
 {
-  grub_free (c->code.combining);
+  grub_unicode_destroy_glyph (&c->code);
   grub_unicode_set_glyph_from_code (&c->code, ' ');
   c->fg_color = virtual_screen.fg_color;
   c->bg_color = virtual_screen.bg_color;
@@ -191,7 +191,7 @@ grub_virtual_screen_free (void)
       for (i = 0;
           i < virtual_screen.columns * virtual_screen.rows;
           i++)
-       grub_free (virtual_screen.text_buffer[i].code.combining);
+       grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code);
       grub_free (virtual_screen.text_buffer);
     }
 
@@ -267,7 +267,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
   /* Clear out text buffer. */
   for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
     {
-      virtual_screen.text_buffer[i].code.combining = 0;
+      virtual_screen.text_buffer[i].code.ncomb = 0;
       clear_char (&(virtual_screen.text_buffer[i]));
     }
 
@@ -408,8 +408,8 @@ grub_gfxterm_term_fini (struct grub_term_output *term __attribute__ ((unused)))
 
   for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
     {
-      grub_free (virtual_screen.text_buffer[i].code.combining);
-      virtual_screen.text_buffer[i].code.combining = 0;
+      grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code);
+      virtual_screen.text_buffer[i].code.ncomb = 0;
       virtual_screen.text_buffer[i].code.base = 0;
     }
 
@@ -651,7 +651,6 @@ paint_char (unsigned cx, unsigned cy)
   /* Mark character to be drawn.  */
   dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
                     width, height);
-  grub_free (glyph);
 }
 
 static inline void
@@ -804,8 +803,8 @@ scroll_up (void)
 
   /* Clear first line in text buffer.  */
   for (i = 0; i < virtual_screen.columns; i++)
-    grub_free (virtual_screen.text_buffer[i].code.combining);
-
+    grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code);
+  
   /* Scroll text buffer with one line to up.  */
   grub_memmove (virtual_screen.text_buffer,
                 virtual_screen.text_buffer + virtual_screen.columns,
@@ -877,7 +876,7 @@ grub_gfxterm_putchar (struct grub_term_output *term,
       p = (virtual_screen.text_buffer +
            virtual_screen.cursor_x +
            virtual_screen.cursor_y * virtual_screen.columns);
-      grub_free (p->code.combining);
+      grub_unicode_destroy_glyph (&p->code);
       grub_unicode_set_glyph (&p->code, c);
       grub_errno = GRUB_ERR_NONE;
       p->fg_color = virtual_screen.fg_color;
@@ -892,7 +891,7 @@ grub_gfxterm_putchar (struct grub_term_output *term,
                 virtual_screen.text_buffer + virtual_screen.columns
                 * virtual_screen.rows; i++)
              {
-               grub_free (p[i].code.combining);
+               grub_unicode_destroy_glyph (&p[i].code);
                p[i].code.base = 0;
              }
         }
index 68c61ffd06a25555d3111e61434fb6ea2bd89ad4..ec9d33a0b0f1159f8dd61ab730646ef9a9f70134 100644 (file)
@@ -478,6 +478,11 @@ int genfd = -1;
 
 #include <grub/time.h>
 
+#if defined (GRUB_MACHINE_EMU) && defined (COLLECT_TIME_STATISTICS)
+#include <sys/times.h>
+#include <unistd.h>
+#endif
+
 static void
 write_time (void)
 {
@@ -486,9 +491,12 @@ write_time (void)
   static grub_uint64_t prev;
   grub_uint64_t cur;
   static int tmrfd = -1;
+  struct tms tm;
   if (tmrfd < 0)
     tmrfd = open ("time.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
-  cur = grub_get_time_ms ();
+
+  times (&tm); 
+  cur = (tm.tms_utime * 1000ULL) / sysconf(_SC_CLK_TCK);
   grub_snprintf (buf, sizeof (buf), "%s_%dx%dx%s:%d: %" PRIuGRUB_UINT64_T " ms\n",
                 basename,                      
                 capt_mode_info.width,
index c206ac872833e4aabdd9398ec3728544a373ae01..789507e28386b17d688855431ef71b151a0db03b 100644 (file)
@@ -1085,15 +1085,9 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
        {
          color = *srcptr++;
 
-#ifdef GRUB_CPU_WORDS_BIGENDIAN
-         sb = (color >> 0) & 0xFF;
-         sg = (color >> 8) & 0xFF;
-         sr = (color >> 16) & 0xFF;
-#else
          sr = (color >> 0) & 0xFF;
          sg = (color >> 8) & 0xFF;
          sb = (color >> 16) & 0xFF;
-#endif
 
          color = grub_video_fb_map_rgb(sr, sg, sb);
          *dstptr++ = color & 0xFF;
index 7f9e4e158260ba1ec0db6bb15423c28093363d5e..4da9c4758c9ba6cc4be3fa77dec37b5ff5ca9ce5 100644 (file)
@@ -5,3 +5,5 @@ void EXPORT_FUNC (write) (void);
 void EXPORT_FUNC (ioctl) (void);
 void EXPORT_FUNC (__errno_location) (void);
 void EXPORT_FUNC (strerror) (void);
+void EXPORT_FUNC (sysconf) (void);
+void EXPORT_FUNC (times) (void);
index 3d79c4c5e1556a077427f337ce5c63879baaa250..d38ddbf62842795b21693dfb2dab1eca60eb2c5c 100644 (file)
@@ -132,21 +132,33 @@ enum grub_comb_type
     GRUB_UNICODE_COMB_MN = 255,
   };
 
+struct grub_unicode_combining
+{
+  grub_uint32_t code:21;
+  enum grub_comb_type type:8;
+};
 /* This structure describes a glyph as opposed to character.  */
 struct grub_unicode_glyph
 {
-  grub_uint32_t base;
-  grub_uint16_t variant:9;
-  grub_uint8_t attributes:5;
-  grub_size_t ncomb;
-  grub_size_t orig_pos;
-  struct grub_unicode_combining {
-    grub_uint32_t code;
-    enum grub_comb_type type;
-  } *combining;
+  grub_uint32_t base:23; /* minimum: 21 */
+  grub_uint16_t variant:9; /* minimum: 9 */
+
+  grub_uint8_t attributes:5; /* minimum: 5 */
+  grub_uint8_t bidi_level:6; /* minimum: 6 */
+  enum grub_bidi_type bidi_type:5; /* minimum: :5 */
+
+  unsigned ncomb:8;
   /* Hint by unicode subsystem how wide this character usually is.
      Real width is determined by font. Set only in UTF-8 stream.  */
-  int estimated_width;
+  int estimated_width:8;
+
+  grub_size_t orig_pos;
+  union
+  {
+    struct grub_unicode_combining combining_inline[sizeof (void *)
+                                                  / sizeof (struct grub_unicode_combining)];
+    struct grub_unicode_combining *combining_ptr;
+  };
 };
 
 #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1
@@ -253,6 +265,24 @@ grub_size_t
 grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
                              struct grub_unicode_glyph *out);
 
+static inline const struct grub_unicode_combining *
+grub_unicode_get_comb (const struct grub_unicode_glyph *in)
+{
+  if (in->ncomb == 0)
+    return NULL;
+  if (in->ncomb > ARRAY_SIZE (in->combining_inline))
+    return in->combining_ptr;
+  return in->combining_inline;
+}
+
+static inline void
+grub_unicode_destroy_glyph (struct grub_unicode_glyph *glyph)
+{
+  if (glyph->ncomb > ARRAY_SIZE (glyph->combining_inline))
+    grub_free (glyph->combining_ptr);
+  glyph->ncomb = 0;
+}
+
 static inline struct grub_unicode_glyph *
 grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
 {
@@ -260,17 +290,20 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
   if (!out)
     return NULL;
   grub_memcpy (out, in, sizeof (*in));
-  if (in->combining)
+  if (in->ncomb > ARRAY_SIZE (out->combining_inline))
     {
-      out->combining = grub_malloc (in->ncomb * sizeof (out->combining[0]));
-      if (!out->combining)
+      out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
+      if (!out->combining_ptr)
        {
          grub_free (out);
          return NULL;
        }
-      grub_memcpy (out->combining, in->combining,
-                  in->ncomb * sizeof (out->combining[0]));
+      grub_memcpy (out->combining_ptr, in->combining_ptr,
+                  in->ncomb * sizeof (out->combining_ptr[0]));
     }
+  else
+    grub_memcpy (&out->combining_inline, &in->combining_inline,
+                sizeof (out->combining_inline));
   return out;
 }
 
@@ -279,14 +312,17 @@ grub_unicode_set_glyph (struct grub_unicode_glyph *out,
                        const struct grub_unicode_glyph *in)
 {
   grub_memcpy (out, in, sizeof (*in));
-  if (in->combining)
+  if (in->ncomb > ARRAY_SIZE (out->combining_inline))
     {
-      out->combining = grub_malloc (in->ncomb * sizeof (out->combining[0]));
-      if (!out->combining)
+      out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
+      if (!out->combining_ptr)
        return;
-      grub_memcpy (out->combining, in->combining,
-                  in->ncomb * sizeof (out->combining[0]));
+      grub_memcpy (out->combining_ptr, in->combining_ptr,
+                  in->ncomb * sizeof (out->combining_ptr[0]));
     }
+  else
+    grub_memcpy (&out->combining_inline, &in->combining_inline,
+                sizeof (out->combining_inline));
 }
 
 static inline struct grub_unicode_glyph *