1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/shaderobj.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_cache.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/program.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct cache_item
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint hash;
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *key;
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program *program;
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item *next;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_program_cache
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item **items;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item *last;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint size, n_items;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute hash index from state key.
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLuint
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orghash_key(const void *key, GLuint key_size)
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint *ikey = (const GLuint *) key;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint hash = 0, i;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(key_size >= 4);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Make a slightly better attempt at a hash function:
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < key_size / sizeof(*ikey); i++)
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      hash += ikey[i];
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      hash += (hash << 10);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      hash ^= (hash >> 6);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return hash;
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Rebuild/expand the hash table to accomodate more entries
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrehash(struct gl_program_cache *cache)
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item **items;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item *c, *next;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint size, i;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->last = NULL;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   size = cache->size * 3;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   items = (struct cache_item**) malloc(size * sizeof(*items));
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(items, 0, size * sizeof(*items));
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < cache->size; i++)
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (c = cache->items[i]; c; c = next) {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 next = c->next;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 c->next = items[c->hash % size];
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 items[c->hash % size] = c;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(cache->items);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->items = items;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->size = size;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclear_cache(struct gl_context *ctx, struct gl_program_cache *cache,
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    GLboolean shader)
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item *c, *next;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLuint i;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->last = NULL;
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < cache->size; i++) {
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (c = cache->items[i]; c; c = next) {
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 next = c->next;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 free(c->key);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (shader) {
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_reference_shader_program(ctx,
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   (struct gl_shader_program **)&c->program,
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   NULL);
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 } else {
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    _mesa_reference_program(ctx, &c->program, NULL);
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 free(c);
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cache->items[i] = NULL;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->n_items = 0;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_program_cache *
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_new_program_cache(void)
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cache) {
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cache->size = 17;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cache->items = (struct cache_item **)
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         calloc(1, cache->size * sizeof(struct cache_item));
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!cache->items) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         free(cache);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return cache;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_delete_program_cache(struct gl_context *ctx, struct gl_program_cache *cache)
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   clear_cache(ctx, cache, GL_FALSE);
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(cache->items);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(cache);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_delete_shader_cache(struct gl_context *ctx,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct gl_program_cache *cache)
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   clear_cache(ctx, cache, GL_TRUE);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(cache->items);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(cache);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_program *
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_search_program_cache(struct gl_program_cache *cache,
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const void *key, GLuint keysize)
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cache->last &&
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       memcmp(cache->last->key, key, keysize) == 0) {
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return cache->last->program;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const GLuint hash = hash_key(key, keysize);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct cache_item *c;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (c = cache->items[hash % cache->size]; c; c = c->next) {
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (c->hash == hash && memcmp(c->key, key, keysize) == 0) {
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            cache->last = c;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return c->program;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_program_cache_insert(struct gl_context *ctx,
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct gl_program_cache *cache,
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const void *key, GLuint keysize,
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct gl_program *program)
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint hash = hash_key(key, keysize);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item *c = CALLOC_STRUCT(cache_item);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->hash = hash;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->key = malloc(keysize);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(c->key, key, keysize);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->program = program;  /* no refcount change */
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cache->n_items > cache->size * 1.5) {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cache->size < 1000)
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 rehash(cache);
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 clear_cache(ctx, cache, GL_FALSE);
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->n_items++;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->next = cache->items[hash % cache->size];
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->items[hash % cache->size] = c;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_shader_cache_insert(struct gl_context *ctx,
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct gl_program_cache *cache,
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  const void *key, GLuint keysize,
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			  struct gl_shader_program *program)
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const GLuint hash = hash_key(key, keysize);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct cache_item *c = CALLOC_STRUCT(cache_item);
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->hash = hash;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->key = malloc(keysize);
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(c->key, key, keysize);
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->program = (struct gl_program *)program;  /* no refcount change */
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cache->n_items > cache->size * 1.5) {
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cache->size < 1000)
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 rehash(cache);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 clear_cache(ctx, cache, GL_TRUE);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->n_items++;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   c->next = cache->items[hash % cache->size];
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cache->items[hash % cache->size] = c;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
252