Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprog_cache.c
Go to the documentation of this file.
00001 /************************************************************************** 00002 * 00003 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 00004 * All Rights Reserved. 00005 * 00006 * Permission is hereby granted, free of charge, to any person obtaining a 00007 * copy of this software and associated documentation files (the 00008 * "Software"), to deal in the Software without restriction, including 00009 * without limitation the rights to use, copy, modify, merge, publish, 00010 * distribute, sub license, and/or sell copies of the Software, and to 00011 * permit persons to whom the Software is furnished to do so, subject to 00012 * the following conditions: 00013 * 00014 * The above copyright notice and this permission notice (including the 00015 * next paragraph) shall be included in all copies or substantial portions 00016 * of the Software. 00017 * 00018 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00019 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00020 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 00021 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 00022 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 00023 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 00024 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00025 * 00026 **************************************************************************/ 00027 00028 00029 #include "main/glheader.h" 00030 #include "main/mtypes.h" 00031 #include "main/imports.h" 00032 #include "shader/prog_cache.h" 00033 #include "shader/program.h" 00034 00035 00036 struct cache_item 00037 { 00038 GLuint hash; 00039 void *key; 00040 struct gl_program *program; 00041 struct cache_item *next; 00042 }; 00043 00044 struct gl_program_cache 00045 { 00046 struct cache_item **items; 00047 GLuint size, n_items; 00048 }; 00049 00050 00051 00055 static GLuint 00056 hash_key(const void *key, GLuint key_size) 00057 { 00058 const GLuint *ikey = (const GLuint *) key; 00059 GLuint hash = 0, i; 00060 00061 assert(key_size >= 4); 00062 00063 /* Make a slightly better attempt at a hash function: 00064 */ 00065 for (i = 0; i < key_size / sizeof(*ikey); i++) 00066 { 00067 hash += ikey[i]; 00068 hash += (hash << 10); 00069 hash ^= (hash >> 6); 00070 } 00071 00072 return hash; 00073 } 00074 00075 00079 static void 00080 rehash(struct gl_program_cache *cache) 00081 { 00082 struct cache_item **items; 00083 struct cache_item *c, *next; 00084 GLuint size, i; 00085 00086 size = cache->size * 3; 00087 items = (struct cache_item**) _mesa_malloc(size * sizeof(*items)); 00088 _mesa_memset(items, 0, size * sizeof(*items)); 00089 00090 for (i = 0; i < cache->size; i++) 00091 for (c = cache->items[i]; c; c = next) { 00092 next = c->next; 00093 c->next = items[c->hash % size]; 00094 items[c->hash % size] = c; 00095 } 00096 00097 _mesa_free(cache->items); 00098 cache->items = items; 00099 cache->size = size; 00100 } 00101 00102 00103 static void 00104 clear_cache(GLcontext *ctx, struct gl_program_cache *cache) 00105 { 00106 struct cache_item *c, *next; 00107 GLuint i; 00108 00109 for (i = 0; i < cache->size; i++) { 00110 for (c = cache->items[i]; c; c = next) { 00111 next = c->next; 00112 _mesa_free(c->key); 00113 _mesa_reference_program(ctx, &c->program, NULL); 00114 _mesa_free(c); 00115 } 00116 cache->items[i] = NULL; 00117 } 00118 00119 00120 cache->n_items = 0; 00121 } 00122 00123 00124 00125 struct gl_program_cache * 00126 _mesa_new_program_cache(void) 00127 { 00128 struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache); 00129 if (cache) { 00130 cache->size = 17; 00131 cache->items = (struct cache_item **) 00132 _mesa_calloc(cache->size * sizeof(struct cache_item)); 00133 if (!cache->items) { 00134 _mesa_free(cache); 00135 return NULL; 00136 } 00137 } 00138 return cache; 00139 } 00140 00141 00142 void 00143 _mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache) 00144 { 00145 clear_cache(ctx, cache); 00146 _mesa_free(cache->items); 00147 _mesa_free(cache); 00148 } 00149 00150 00151 struct gl_program * 00152 _mesa_search_program_cache(const struct gl_program_cache *cache, 00153 const void *key, GLuint keysize) 00154 { 00155 const GLuint hash = hash_key(key, keysize); 00156 struct cache_item *c; 00157 00158 for (c = cache->items[hash % cache->size]; c; c = c->next) { 00159 if (c->hash == hash && memcmp(c->key, key, keysize) == 0) 00160 return c->program; 00161 } 00162 00163 return NULL; 00164 } 00165 00166 00167 void 00168 _mesa_program_cache_insert(GLcontext *ctx, 00169 struct gl_program_cache *cache, 00170 const void *key, GLuint keysize, 00171 struct gl_program *program) 00172 { 00173 const GLuint hash = hash_key(key, keysize); 00174 struct cache_item *c = CALLOC_STRUCT(cache_item); 00175 00176 c->hash = hash; 00177 00178 c->key = _mesa_malloc(keysize); 00179 memcpy(c->key, key, keysize); 00180 00181 c->program = program; /* no refcount change */ 00182 00183 if (cache->n_items > cache->size * 1.5) { 00184 if (cache->size < 1000) 00185 rehash(cache); 00186 else 00187 clear_cache(ctx, cache); 00188 } 00189 00190 cache->n_items++; 00191 c->next = cache->items[hash % cache->size]; 00192 cache->items[hash % cache->size] = c; 00193 } Generated on Sun May 27 2012 04:20:34 for ReactOS by
1.7.6.1
|