Going through the for loop every time has noticable overhead. This fixes things up so we only do that once ever and then just do a hash table lookup which should be much cheaper. --- src/mesa/main/formats.c | 67 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 11 deletions(-)
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 8ac0583..f125a13 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -28,6 +28,7 @@ #include "formats.h" #include "macros.h" #include "glformats.h" +#include "util/hash_table.h" /** @@ -377,24 +378,68 @@ _mesa_format_to_array_format(mesa_format format) return _mesa_array_format_flip_channels(info->ArrayFormat); } +static struct hash_table *format_array_format_table; +static pthread_once_t format_array_format_table_exists = PTHREAD_ONCE_INIT; + +static bool +array_formats_equal(const void *a, const void *b) +{ + return (intptr_t)a == (intptr_t)b; +} + +static void +format_array_format_table_init() +{ + const struct gl_format_info *info; + mesa_array_format array_format; + unsigned f; + + format_array_format_table = _mesa_hash_table_create(NULL, NULL, + array_formats_equal); + + for (f = 1; f < MESA_FORMAT_COUNT; ++f) { + info = _mesa_get_format_info(f); + if (!info->ArrayFormat) + continue; + + if (_mesa_little_endian()) { + array_format = info->ArrayFormat; + } else { + array_format = _mesa_array_format_flip_channels(info->ArrayFormat); + } + + /* This can happen and does for some of the BGR formats. Let's take + * the first one in the list. + */ + if (_mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format)) + continue; + + _mesa_hash_table_insert_with_hash(format_array_format_table, + array_format, + (void *)(intptr_t)array_format, + (void *)(intptr_t)f); + } +} + mesa_format _mesa_format_from_array_format(uint32_t array_format) { - mesa_array_format af; - unsigned f; + struct hash_entry *entry; assert(_mesa_format_is_mesa_array_format(array_format)); - if (_mesa_little_endian()) - af = array_format; - else - af = _mesa_array_format_flip_channels(array_format); - - for (f = 1; f < MESA_FORMAT_COUNT; ++f) - if (_mesa_get_format_info(f)->ArrayFormat == af) - return f; + pthread_once(&format_array_format_table_exists, + format_array_format_table_init); - return MESA_FORMAT_NONE; + entry = _mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format); + if (entry) + return (intptr_t)entry->data; + else + return MESA_FORMAT_NONE; } /** Is the given format a compressed format? */ -- 2.2.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev