ReactOS 0.4.16-dev-2354-g16de117
ftccache.c File Reference
#include "ftcmanag.h"
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftdebug.h>
#include "ftccback.h"
#include "ftcerror.h"
Include dependency graph for ftccache.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FT_COMPONENT   cache
 
#define FTC_HASH_MAX_LOAD   2
 
#define FTC_HASH_MIN_LOAD   1
 
#define FTC_HASH_SUB_LOAD   ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )
 
#define FTC_HASH_INITIAL_SIZE   8
 

Functions

static void ftc_node_mru_link (FTC_Node node, FTC_Manager manager)
 
static void ftc_node_mru_unlink (FTC_Node node, FTC_Manager manager)
 
static void ftc_cache_resize (FTC_Cache cache)
 
static void ftc_node_hash_unlink (FTC_Node node0, FTC_Cache cache)
 
static void ftc_node_hash_link (FTC_Node node, FTC_Cache cache)
 
 ftc_node_destroy (FTC_Node node, FTC_Manager manager)
 
 FTC_Cache_Init (FTC_Cache cache)
 
 ftc_cache_init (FTC_Cache cache)
 
static void FTC_Cache_Clear (FTC_Cache cache)
 
 ftc_cache_done (FTC_Cache cache)
 
 FTC_Cache_Done (FTC_Cache cache)
 
static void ftc_cache_add (FTC_Cache cache, FT_Offset hash, FTC_Node node)
 
 FTC_Cache_NewNode (FTC_Cache cache, FT_Offset hash, FT_Pointer query, FTC_Node *anode)
 
 FTC_Cache_RemoveFaceID (FTC_Cache cache, FTC_FaceID face_id)
 

Macro Definition Documentation

◆ FT_COMPONENT

#define FT_COMPONENT   cache

Definition at line 27 of file ftccache.c.

◆ FTC_HASH_INITIAL_SIZE

#define FTC_HASH_INITIAL_SIZE   8

Definition at line 35 of file ftccache.c.

◆ FTC_HASH_MAX_LOAD

#define FTC_HASH_MAX_LOAD   2

Definition at line 30 of file ftccache.c.

◆ FTC_HASH_MIN_LOAD

#define FTC_HASH_MIN_LOAD   1

Definition at line 31 of file ftccache.c.

◆ FTC_HASH_SUB_LOAD

#define FTC_HASH_SUB_LOAD   ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD )

Definition at line 32 of file ftccache.c.

Function Documentation

◆ ftc_cache_add()

static void ftc_cache_add ( FTC_Cache  cache,
FT_Offset  hash,
FTC_Node  node 
)
static

Definition at line 415 of file ftccache.c.

418 {
419 node->hash = hash;
420 node->cache_index = (FT_UInt16)cache->index;
421 node->ref_count = 0;
422
424 ftc_node_mru_link( node, cache->manager );
425
426 {
427 FTC_Manager manager = cache->manager;
428
429
430 manager->cur_weight += cache->clazz.node_weight( node, cache );
431
432 if ( manager->cur_weight >= manager->max_weight )
433 {
434 node->ref_count++;
435 FTC_Manager_Compress( manager );
436 node->ref_count--;
437 }
438 }
439 }
static void ftc_node_mru_link(FTC_Node node, FTC_Manager manager)
Definition: ftccache.c:48
static void ftc_node_hash_link(FTC_Node node, FTC_Cache cache)
Definition: ftccache.c:256
FTC_Manager_Compress(FTC_Manager manager)
Definition: ftcmanag.c:533
unsigned short FT_UInt16
Definition: integer-types.h:90
FT_Offset cur_weight
Definition: ftcmanag.h:97
FT_Offset max_weight
Definition: ftcmanag.h:96
Definition: cache.c:49
Definition: _hash_fun.h:40
Definition: dlist.c:348

Referenced by FTC_Cache_NewNode().

◆ FTC_Cache_Clear()

static void FTC_Cache_Clear ( FTC_Cache  cache)
static

Definition at line 350 of file ftccache.c.

351 {
352 if ( cache && cache->buckets )
353 {
354 FTC_Manager manager = cache->manager;
355 FT_UFast i;
356 FT_UFast count;
357
358
359 count = cache->p + cache->mask + 1;
360
361 for ( i = 0; i < count; i++ )
362 {
363 FTC_Node *pnode = cache->buckets + i, next, node = *pnode;
364
365
366 while ( node )
367 {
368 next = node->link;
369 node->link = NULL;
370
371 /* remove node from mru list */
372 ftc_node_mru_unlink( node, manager );
373
374 /* now finalize it */
375 manager->cur_weight -= cache->clazz.node_weight( node, cache );
376
377 cache->clazz.node_free( node, cache );
378 node = next;
379 }
380 cache->buckets[i] = NULL;
381 }
383 }
384 }
#define NULL
Definition: types.h:112
static void ftc_cache_resize(FTC_Cache cache)
Definition: ftccache.c:112
static void ftc_node_mru_unlink(FTC_Node node, FTC_Manager manager)
Definition: ftccache.c:62
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by ftc_cache_done().

◆ ftc_cache_done()

ftc_cache_done ( FTC_Cache  cache)

Definition at line 388 of file ftccache.c.

389 {
390 if ( cache->memory )
391 {
392 FT_Memory memory = cache->memory;
393
394
396
397 FT_FREE( cache->buckets );
398 cache->mask = 0;
399 cache->p = 0;
400 cache->slack = 0;
401
402 cache->memory = NULL;
403 }
404 }
static void FTC_Cache_Clear(FTC_Cache cache)
Definition: ftccache.c:350
#define FT_FREE(ptr)
Definition: ftmemory.h:337
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
static char memory[1024 *256]
Definition: process.c:122

Referenced by FTC_Cache_Done().

◆ FTC_Cache_Done()

FTC_Cache_Done ( FTC_Cache  cache)

Definition at line 408 of file ftccache.c.

409 {
411 }
ftc_cache_done(FTC_Cache cache)
Definition: ftccache.c:388

Referenced by ftc_gcache_done().

◆ FTC_Cache_Init()

FTC_Cache_Init ( FTC_Cache  cache)

Definition at line 327 of file ftccache.c.

328 {
329 return ftc_cache_init( cache );
330 }
ftc_cache_init(FTC_Cache cache)
Definition: ftccache.c:334

Referenced by ftc_gcache_init().

◆ ftc_cache_init()

ftc_cache_init ( FTC_Cache  cache)

Definition at line 334 of file ftccache.c.

335 {
336 FT_Memory memory = cache->memory;
338
339
340 cache->p = 0;
341 cache->mask = FTC_HASH_INITIAL_SIZE - 1;
343
345 return error;
346 }
#define FTC_HASH_INITIAL_SIZE
Definition: ftccache.c:35
#define FTC_HASH_MAX_LOAD
Definition: ftccache.c:30
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:341
int FT_Error
Definition: fttypes.h:299
#define error(str)
Definition: mkdosfs.c:1605

Referenced by FTC_Cache_Init().

◆ FTC_Cache_NewNode()

FTC_Cache_NewNode ( FTC_Cache  cache,
FT_Offset  hash,
FT_Pointer  query,
FTC_Node anode 
)

Definition at line 443 of file ftccache.c.

447 {
450
451
452 /*
453 * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory
454 * errors (OOM) correctly, i.e., by flushing the cache progressively
455 * in order to make more room.
456 */
457
459 {
460 error = cache->clazz.node_new( &node, query, cache );
461 }
463
464 if ( error )
465 node = NULL;
466 else
467 {
468 /* don't assume that the cache has the same number of buckets, since
469 * our allocation request might have triggered global cache flushing
470 */
472 }
473
474 *anode = node;
475 return error;
476 }
static void ftc_cache_add(FTC_Cache cache, FT_Offset hash, FTC_Node node)
Definition: ftccache.c:415
#define FTC_CACHE_TRYLOOP_END(list_changed)
Definition: ftccache.h:323
#define FTC_CACHE_TRYLOOP(cache)
Definition: ftccache.h:312

◆ FTC_Cache_RemoveFaceID()

FTC_Cache_RemoveFaceID ( FTC_Cache  cache,
FTC_FaceID  face_id 
)

Definition at line 563 of file ftccache.c.

565 {
566 FT_UFast i, count;
567 FTC_Manager manager = cache->manager;
568 FTC_Node frees = NULL;
569
570
571 count = cache->p + cache->mask + 1;
572 for ( i = 0; i < count; i++ )
573 {
574 FTC_Node* bucket = cache->buckets + i;
575 FTC_Node* pnode = bucket;
576
577
578 for (;;)
579 {
580 FTC_Node node = *pnode;
581 FT_Bool list_changed = FALSE;
582
583
584 if ( !node )
585 break;
586
587 if ( cache->clazz.node_remove_faceid( node, face_id,
588 cache, &list_changed ) )
589 {
590 *pnode = node->link;
591 node->link = frees;
592 frees = node;
593 }
594 else
595 pnode = &node->link;
596 }
597 }
598
599 /* remove all nodes in the free list */
600 while ( frees )
601 {
603
604
605 node = frees;
606 frees = node->link;
607
608 manager->cur_weight -= cache->clazz.node_weight( node, cache );
609 ftc_node_mru_unlink( node, manager );
610
611 cache->clazz.node_free( node, cache );
612
613 cache->slack++;
614 }
615
617 }
#define FALSE
Definition: types.h:117
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108

Referenced by FTC_Manager_RemoveFaceID().

◆ ftc_cache_resize()

static void ftc_cache_resize ( FTC_Cache  cache)
static

Definition at line 112 of file ftccache.c.

113 {
114 for (;;)
115 {
116 FTC_Node node, *pnode;
117 FT_UFast p = cache->p;
118 FT_UFast mask = cache->mask;
119 FT_UFast count = mask + p + 1; /* number of buckets */
120
121
122 /* do we need to shrink the buckets array? */
123 if ( cache->slack < 0 )
124 {
125 FTC_Node new_list = NULL;
126
127
128 /* try to expand the buckets array _before_ splitting
129 * the bucket lists
130 */
131 if ( p >= mask )
132 {
133 FT_Memory memory = cache->memory;
135
136
137 /* if we can't expand the array, leave immediately */
138 if ( FT_RENEW_ARRAY( cache->buckets,
139 ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) )
140 break;
141 }
142
143 /* split a single bucket */
144 pnode = cache->buckets + p;
145
146 for (;;)
147 {
148 node = *pnode;
149 if ( !node )
150 break;
151
152 if ( node->hash & ( mask + 1 ) )
153 {
154 *pnode = node->link;
155 node->link = new_list;
156 new_list = node;
157 }
158 else
159 pnode = &node->link;
160 }
161
162 cache->buckets[p + mask + 1] = new_list;
163
164 cache->slack += FTC_HASH_MAX_LOAD;
165
166 if ( p >= mask )
167 {
168 cache->mask = 2 * mask + 1;
169 cache->p = 0;
170 }
171 else
172 cache->p = p + 1;
173 }
174
175 /* do we need to expand the buckets array? */
176 else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD )
177 {
178 FT_UFast old_index = p + mask;
179 FTC_Node* pold;
180
181
182 if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE )
183 break;
184
185 if ( p == 0 )
186 {
187 FT_Memory memory = cache->memory;
189
190
191 /* if we can't shrink the array, leave immediately */
192 if ( FT_RENEW_ARRAY( cache->buckets,
193 ( mask + 1 ) * 2, mask + 1 ) )
194 break;
195
196 cache->mask >>= 1;
197 p = cache->mask;
198 }
199 else
200 p--;
201
202 pnode = cache->buckets + p;
203 while ( *pnode )
204 pnode = &(*pnode)->link;
205
206 pold = cache->buckets + old_index;
207 *pnode = *pold;
208 *pold = NULL;
209
210 cache->slack -= FTC_HASH_MAX_LOAD;
211 cache->p = p;
212 }
213
214 /* otherwise, the hash table is balanced */
215 else
216 break;
217 }
218 }
#define FTC_HASH_SUB_LOAD
Definition: ftccache.c:32
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:344
signed long FT_Long
Definition: fttypes.h:242
GLenum GLint GLuint mask
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902
FTC_Node link
Definition: ftccache.h:61

Referenced by FTC_Cache_Clear(), FTC_Cache_RemoveFaceID(), ftc_node_hash_link(), and ftc_node_hash_unlink().

◆ ftc_node_destroy()

ftc_node_destroy ( FTC_Node  node,
FTC_Manager  manager 
)

Definition at line 272 of file ftccache.c.

274 {
276
277
278#ifdef FT_DEBUG_ERROR
279 /* find node's cache */
280 if ( node->cache_index >= manager->num_caches )
281 {
282 FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
283 return;
284 }
285#endif
286
287 cache = manager->caches[node->cache_index];
288
289#ifdef FT_DEBUG_ERROR
290 if ( !cache )
291 {
292 FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" ));
293 return;
294 }
295#endif
296
297 manager->cur_weight -= cache->clazz.node_weight( node, cache );
298
299 /* remove node from mru list */
300 ftc_node_mru_unlink( node, manager );
301
302 /* remove node from cache's hash table */
304
305 /* now finalize it */
306 cache->clazz.node_free( node, cache );
307
308#if 0
309 /* check, just in case of general corruption :-) */
310 if ( manager->num_nodes == 0 )
311 FT_TRACE0(( "ftc_node_destroy: invalid cache node count (%d)\n",
312 manager->num_nodes ));
313#endif
314 }
static void ftc_node_hash_unlink(FTC_Node node0, FTC_Cache cache)
Definition: ftccache.c:223
#define FT_TRACE0(varformat)
Definition: ftdebug.h:187
FT_UInt num_caches
Definition: ftcmanag.h:101
FTC_Cache caches[FTC_MAX_CACHES]
Definition: ftcmanag.h:100
FT_UInt num_nodes
Definition: ftcmanag.h:98

Referenced by FTC_Manager_Compress(), and FTC_Manager_FlushN().

◆ ftc_node_hash_link()

static void ftc_node_hash_link ( FTC_Node  node,
FTC_Cache  cache 
)
static

Definition at line 256 of file ftccache.c.

258 {
259 FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node->hash );
260
261
262 node->link = *pnode;
263 *pnode = node;
264
265 cache->slack--;
267 }
#define FTC_NODE_TOP_FOR_HASH(cache, hash)
Definition: ftccache.h:76

Referenced by ftc_cache_add().

◆ ftc_node_hash_unlink()

static void ftc_node_hash_unlink ( FTC_Node  node0,
FTC_Cache  cache 
)
static

Definition at line 223 of file ftccache.c.

225 {
226 FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node0->hash );
227
228
229 for (;;)
230 {
231 FTC_Node node = *pnode;
232
233
234 if ( !node )
235 {
236 FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" ));
237 return;
238 }
239
240 if ( node == node0 )
241 break;
242
243 pnode = &(*pnode)->link;
244 }
245
246 *pnode = node0->link;
247 node0->link = NULL;
248
249 cache->slack++;
251 }
FT_Offset hash
Definition: ftccache.h:62

Referenced by ftc_node_destroy().

◆ ftc_node_mru_link()

static void ftc_node_mru_link ( FTC_Node  node,
FTC_Manager  manager 
)
static

Definition at line 48 of file ftccache.c.

50 {
51 void *nl = &manager->nodes_list;
52
53
56 manager->num_nodes++;
57 }
FTC_MruNode_Prepend(FTC_MruNode *plist, FTC_MruNode node)
Definition: ftcmru.c:28
typedefFT_BEGIN_HEADER struct FTC_MruNodeRec_ * FTC_MruNode
Definition: ftcmru.h:61
FTC_Node nodes_list
Definition: ftcmanag.h:95

Referenced by ftc_cache_add().

◆ ftc_node_mru_unlink()

static void ftc_node_mru_unlink ( FTC_Node  node,
FTC_Manager  manager 
)
static

Definition at line 62 of file ftccache.c.

64 {
65 void *nl = &manager->nodes_list;
66
67
70 manager->num_nodes--;
71 }
FTC_MruNode_Remove(FTC_MruNode *plist, FTC_MruNode node)
Definition: ftcmru.c:121

Referenced by FTC_Cache_Clear(), FTC_Cache_RemoveFaceID(), and ftc_node_destroy().