From 548a1b5ab7304037a7cac8e6d647fb6b5ccbaf5d Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 30 Mar 2010 16:58:19 -0700 Subject: [PATCH] Implement array type handling Since all glsl_type objects are flyweights, support is added to track all known array types. This accounts for most of the changes. --- glsl_types.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ glsl_types.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/glsl_types.cpp b/glsl_types.cpp index df9667f..8d11196 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -26,8 +26,11 @@ #include "glsl_parser_extras.h" #include "glsl_types.h" #include "builtin_types.h" +#include "hash_table.h" +hash_table *glsl_type::array_types = NULL; + static void add_types_to_symbol_table(glsl_symbol_table *symtab, const struct glsl_type *types, @@ -542,3 +545,49 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns) assert(!"Should not get here."); return error_type; } + + +int +glsl_type::array_key_compare(const void *a, const void *b) +{ + const array_hash_key *const key1 = (array_hash_key *) a; + const array_hash_key *const key2 = (array_hash_key *) b; + + return ((key1->type == key2->type) && (key1->size == key2->size)) ? 0 : 1; +} + + +unsigned +glsl_type::array_key_hash(const void *a) +{ + char buf[sizeof(array_hash_key) + 1]; + + memcpy(buf, a, sizeof(array_hash_key)); + buf[sizeof(array_hash_key)] = '\0'; + + return hash_table_string_hash(buf); +} + + +const glsl_type * +glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) +{ + array_hash_key key = { base, array_size }; + + if (array_types == NULL) { + array_types = hash_table_ctor(64, array_key_hash, array_key_compare); + } + + const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key); + if (t == NULL) { + t = new glsl_type(base, array_size); + + hash_table_insert(array_types, (void *) t, & key); + } + + assert(t->base_type == GLSL_TYPE_ARRAY); + assert(t->length == array_size); + assert(t->fields.array == base); + + return t; +} diff --git a/glsl_types.h b/glsl_types.h index bb2d6f6..6f3b512 100644 --- a/glsl_types.h +++ b/glsl_types.h @@ -170,6 +170,12 @@ struct glsl_type { unsigned columns); /** + * Get the instance of an array type + */ + static const glsl_type *get_array_instance(const glsl_type *base, + unsigned elements); + + /** * Query the total number of scalars that make up a scalar, vector or matrix */ unsigned components() const @@ -301,6 +307,20 @@ struct glsl_type { private: /** + * Constructor for array types + */ + glsl_type(const glsl_type *array, unsigned length) : + base_type(GLSL_TYPE_ARRAY), + sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), + sampler_type(0), + vector_elements(0), matrix_columns(0), + name(NULL), length(length) + { + this->fields.array = array; + this->name = ""; + } + + /** * \name Pointers to various private type singletons */ /*@{*/ @@ -314,6 +334,18 @@ private: static const glsl_type *const mat4x3_type; static const glsl_type *const mat4_type; /*@}*/ + + /** Hash table containing the known array types. */ + static struct hash_table *array_types; + + /** Structure defining the key type used for array_types hash table. */ + struct array_hash_key { + const glsl_type *type; + unsigned size; + }; + + static int array_key_compare(const void *a, const void *b); + static unsigned array_key_hash(const void *key); }; struct glsl_struct_field { -- 2.7.4