slang: Use _mesa_snprintf() wrapper.
[mesa.git] / src / mesa / shader / prog_cache.c
index dd0241ef24ef3cf6314b8c49dbdd971581613cbb..9437e596138e9747235ab3853af7aaa0799e80eb 100644 (file)
@@ -30,6 +30,7 @@
 #include "main/mtypes.h"
 #include "main/imports.h"
 #include "shader/prog_cache.h"
+#include "shader/program.h"
 
 
 struct cache_item
@@ -43,6 +44,7 @@ struct cache_item
 struct gl_program_cache
 {
    struct cache_item **items;
+   struct cache_item *last;
    GLuint size, n_items;
 };
 
@@ -82,6 +84,8 @@ rehash(struct gl_program_cache *cache)
    struct cache_item *c, *next;
    GLuint size, i;
 
+   cache->last = NULL;
+
    size = cache->size * 3;
    items = (struct cache_item**) _mesa_malloc(size * sizeof(*items));
    _mesa_memset(items, 0, size * sizeof(*items));
@@ -104,12 +108,14 @@ clear_cache(GLcontext *ctx, struct gl_program_cache *cache)
 {
    struct cache_item *c, *next;
    GLuint i;
+   
+   cache->last = NULL;
 
    for (i = 0; i < cache->size; i++) {
       for (c = cache->items[i]; c; c = next) {
         next = c->next;
         _mesa_free(c->key);
-        ctx->Driver.DeleteProgram(ctx, c->program);
+         _mesa_reference_program(ctx, &c->program, NULL);
         _mesa_free(c);
       }
       cache->items[i] = NULL;
@@ -148,18 +154,26 @@ _mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache)
 
 
 struct gl_program *
-_mesa_search_program_cache(const struct gl_program_cache *cache,
+_mesa_search_program_cache(struct gl_program_cache *cache,
                            const void *key, GLuint keysize)
 {
-   const GLuint hash = hash_key(key, keysize);
-   struct cache_item *c;
-
-   for (c = cache->items[hash % cache->size]; c; c = c->next) {
-      if (c->hash == hash && memcmp(c->key, key, keysize) == 0)
-        return c->program;
+   if (cache->last && 
+       memcmp(cache->last->key, key, keysize) == 0) {
+      return cache->last->program;
    }
+   else {
+      const GLuint hash = hash_key(key, keysize);
+      struct cache_item *c;
+
+      for (c = cache->items[hash % cache->size]; c; c = c->next) {
+         if (c->hash == hash && memcmp(c->key, key, keysize) == 0) {
+            cache->last = c;
+            return c->program;
+         }
+      }
 
-   return NULL;
+      return NULL;
+   }
 }
 
 
@@ -177,7 +191,7 @@ _mesa_program_cache_insert(GLcontext *ctx,
    c->key = _mesa_malloc(keysize);
    memcpy(c->key, key, keysize);
 
-   c->program = program;
+   c->program = program;  /* no refcount change */
 
    if (cache->n_items > cache->size * 1.5) {
       if (cache->size < 1000)