+static void rehash( struct texenvprog_cache *cache )
+{
+ struct texenvprog_cache_item **items;
+ struct texenvprog_cache_item *c, *next;
+ GLuint size, i;
+
+ size = cache->size * 3;
+ items = (struct texenvprog_cache_item**) _mesa_malloc(size * sizeof(*items));
+ _mesa_memset(items, 0, size * sizeof(*items));
+
+ for (i = 0; i < cache->size; i++)
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ c->next = items[c->hash % size];
+ items[c->hash % size] = c;
+ }
+
+ _mesa_free(cache->items);
+ cache->items = items;
+ cache->size = size;
+}
+
+static void clear_cache( struct texenvprog_cache *cache )
+{
+ struct texenvprog_cache_item *c, *next;
+ GLuint i;
+
+ for (i = 0; i < cache->size; i++) {
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ _mesa_free(c->key);
+ cache->ctx->Driver.DeleteProgram(cache->ctx,
+ (struct gl_program *) c->data);
+ _mesa_free(c);
+ }
+ cache->items[i] = NULL;
+ }
+
+
+ cache->n_items = 0;
+}
+
+
+static void cache_item( struct texenvprog_cache *cache,