Nikolay Sivov : dwrite: Prefetch all lookup entry fields when collecting them.

Alexandre Julliard julliard at winehq.org
Tue May 26 17:17:06 CDT 2020


Module: wine
Branch: master
Commit: 2b5500ce1213374b602cb3eead580f5dfc985b2b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2b5500ce1213374b602cb3eead580f5dfc985b2b

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue May 26 11:16:11 2020 +0300

dwrite: Prefetch all lookup entry fields when collecting them.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dwrite/opentype.c | 98 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 59 insertions(+), 39 deletions(-)

diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 54d066e017..7e35feb7f5 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -4159,7 +4159,12 @@ static void opentype_layout_apply_gpos_lookup(struct scriptshaping_context *cont
 struct lookup
 {
     unsigned short index;
+    unsigned short type;
+    unsigned short flags;
+    unsigned short subtable_count;
+
     unsigned int mask;
+    unsigned int offset;
 };
 
 struct lookups
@@ -4176,11 +4181,45 @@ static int lookups_sorting_compare(const void *a, const void *b)
     return left->index < right->index ? -1 : left->index > right->index ? 1 : 0;
 };
 
+static BOOL opentype_layout_init_lookup(struct ot_gsubgpos_table *table, unsigned short lookup_index, unsigned int mask,
+        struct lookup *lookup)
+{
+    unsigned short subtable_count, lookup_type, flags;
+    const struct ot_lookup_table *lookup_table;
+    unsigned int offset;
+
+    if (!(offset = table_read_be_word(&table->table, table->lookup_list +
+            FIELD_OFFSET(struct ot_lookup_list, lookup[lookup_index]))))
+    {
+        return FALSE;
+    }
+
+    offset += table->lookup_list;
+
+    if (!(lookup_table = table_read_ensure(&table->table, offset, sizeof(*lookup_table))))
+        return FALSE;
+
+    if (!(subtable_count = GET_BE_WORD(lookup_table->subtable_count)))
+        return FALSE;
+
+    lookup_type = GET_BE_WORD(lookup_table->lookup_type);
+    flags = GET_BE_WORD(lookup_table->flags);
+
+    lookup->index = lookup_index;
+    lookup->type = lookup_type;
+    lookup->flags = flags;
+    lookup->subtable_count = subtable_count;
+    lookup->mask = mask;
+    lookup->offset = offset;
+
+    return TRUE;
+}
+
 static void opentype_layout_add_lookups(const struct ot_feature_list *feature_list, UINT16 total_lookup_count,
         struct ot_gsubgpos_table *table, struct shaping_feature *feature, struct lookups *lookups)
 {
     UINT16 feature_offset, lookup_count;
-    unsigned int i, j;
+    unsigned int i;
 
     /* Feature wasn't found */
     if (feature->index == 0xffff)
@@ -4211,10 +4250,8 @@ static void opentype_layout_add_lookups(const struct ot_feature_list *feature_li
         if (lookup_index >= total_lookup_count)
             continue;
 
-        j = lookups->count;
-        lookups->lookups[j].index = lookup_index;
-        lookups->lookups[j].mask = feature->mask;
-        lookups->count++;
+        if (opentype_layout_init_lookup(table, lookup_index, feature->mask, &lookups->lookups[lookups->count]))
+            lookups->count++;
     }
 }
 
@@ -4424,7 +4461,7 @@ void opentype_layout_apply_gpos_features(struct scriptshaping_context *context,
     heap_free(lookups.lookups);
 }
 
-static BOOL opentype_layout_apply_gsub_single_substitution(struct glyph_iterator *iter, const struct ot_lookup *lookup)
+static BOOL opentype_layout_apply_gsub_single_substitution(struct glyph_iterator *iter, const struct lookup *lookup)
 {
     UINT16 format, coverage, orig_glyph = iter->context->u.subst.glyphs[iter->pos], glyph = orig_glyph;
     struct scriptshaping_cache *cache = iter->context->cache;
@@ -4550,16 +4587,19 @@ static BOOL opentype_layout_context_match_lookahead(struct glyph_iterator *iter,
 }
 
 static void opentype_layout_apply_gsub_lookup(struct scriptshaping_context *context, unsigned int first_glyph,
-        unsigned int glyph_count, int lookup_index, BOOL only_single);
+        unsigned int glyph_count, struct lookup *lookup, BOOL only_single);
 
 static BOOL opentype_layout_context_gsub_apply_lookup(struct glyph_iterator *iter, unsigned int count,
         unsigned int lookup_count, const UINT16 *lookup_records)
 {
+    struct lookup lookup = { 0 };
+
     if (lookup_count > 1)
         FIXME("Only first lookup used.\n");
 
-    opentype_layout_apply_gsub_lookup(iter->context, iter->pos + GET_BE_WORD(lookup_records[0]), count,
-            GET_BE_WORD(lookup_records[1]), TRUE);
+    if (opentype_layout_init_lookup(&iter->context->cache->gsub, GET_BE_WORD(lookup_records[1]), 0, &lookup))
+        opentype_layout_apply_gsub_lookup(iter->context, iter->pos + GET_BE_WORD(lookup_records[0]), count,
+                &lookup, TRUE);
 
     return TRUE;
 }
@@ -4574,7 +4614,7 @@ static BOOL opentype_layout_apply_gsub_chain_context_lookup(struct glyph_iterato
             opentype_layout_context_gsub_apply_lookup(iter, input_count, lookup_count, lookup_records);
 }
 
-static BOOL opentype_layout_apply_gsub_chain_context_substitution(struct glyph_iterator *iter, const struct ot_lookup *lookup)
+static BOOL opentype_layout_apply_gsub_chain_context_substitution(struct glyph_iterator *iter, const struct lookup *lookup)
 {
     struct scriptshaping_cache *cache = iter->context->cache;
     UINT16 format, coverage;
@@ -4661,34 +4701,14 @@ static BOOL opentype_layout_apply_gsub_chain_context_substitution(struct glyph_i
 }
 
 static void opentype_layout_apply_gsub_lookup(struct scriptshaping_context *context, unsigned int first_glyph,
-        unsigned int glyph_count, int lookup_index, BOOL only_single)
+        unsigned int glyph_count, struct lookup *lookup, BOOL only_single)
 {
-    struct ot_gsubgpos_table *table = &context->cache->gsub;
-    const struct ot_lookup_table *lookup_table;
     struct glyph_iterator iter;
-    struct ot_lookup lookup;
-    WORD lookup_type;
 
-    lookup.offset = table_read_be_word(&table->table, table->lookup_list + FIELD_OFFSET(struct ot_lookup_list, lookup[lookup_index]));
-    if (!lookup.offset)
+    if (lookup->type != GSUB_LOOKUP_SINGLE_SUBST && only_single)
         return;
 
-    lookup.offset += table->lookup_list;
-
-    if (!(lookup_table = table_read_ensure(&table->table, lookup.offset, sizeof(*lookup_table))))
-        return;
-
-    lookup.subtable_count = GET_BE_WORD(lookup_table->subtable_count);
-    if (!lookup.subtable_count)
-        return;
-
-    lookup_type = GET_BE_WORD(lookup_table->lookup_type);
-    lookup.flags = GET_BE_WORD(lookup_table->flags);
-
-    if (lookup_type != GSUB_LOOKUP_SINGLE_SUBST && only_single)
-        return;
-
-    glyph_iterator_init(context, lookup.flags, first_glyph, glyph_count, &iter);
+    glyph_iterator_init(context, lookup->flags, first_glyph, glyph_count, &iter);
 
     while (iter.pos < first_glyph + iter.len)
     {
@@ -4700,13 +4720,13 @@ static void opentype_layout_apply_gsub_lookup(struct scriptshaping_context *cont
             continue;
         }
 
-        switch (lookup_type)
+        switch (lookup->type)
         {
             case GSUB_LOOKUP_SINGLE_SUBST:
-                ret = opentype_layout_apply_gsub_single_substitution(&iter, &lookup);
+                ret = opentype_layout_apply_gsub_single_substitution(&iter, lookup);
                 break;
             case GSUB_LOOKUP_CHAINING_CONTEXTUAL_SUBST:
-                ret = opentype_layout_apply_gsub_chain_context_substitution(&iter, &lookup);
+                ret = opentype_layout_apply_gsub_chain_context_substitution(&iter, lookup);
                 break;
             case GSUB_LOOKUP_MULTIPLE_SUBST:
             case GSUB_LOOKUP_ALTERNATE_SUBST:
@@ -4714,10 +4734,10 @@ static void opentype_layout_apply_gsub_lookup(struct scriptshaping_context *cont
             case GSUB_LOOKUP_CONTEXTUAL_SUBST:
             case GSUB_LOOKUP_REVERSE_CHAINING_CONTEXTUAL_SUBST:
                 ret = FALSE;
-                WARN("Unimplemented lookup %d.\n", lookup_type);
+                WARN("Unimplemented lookup %d.\n", lookup->type);
                 break;
             default:
-                WARN("Unknown lookup type %u.\n", lookup_type);
+                WARN("Unknown lookup type %u.\n", lookup->type);
                 return;
         }
 
@@ -4801,7 +4821,7 @@ HRESULT opentype_layout_apply_gsub_features(struct scriptshaping_context *contex
     opentype_layout_set_glyph_masks(context, features);
 
     for (i = 0; i < lookups.count; ++i)
-        opentype_layout_apply_gsub_lookup(context, 0, context->glyph_count, lookups.lookups[i].index, FALSE);
+        opentype_layout_apply_gsub_lookup(context, 0, context->glyph_count, &lookups.lookups[i], FALSE);
 
     heap_free(lookups.lookups);
 




More information about the wine-cvs mailing list