ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

prog_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.