1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include "pch.h"
#include "Cache.h"
Cache::Cache(void)
{
this->size = 0;
this->head = NULL;
this->tail = NULL;
}
Cache::~Cache(void)
{
}
void Cache::Empty(fz_context *mu_ctx)
{
if (this != nullptr) {
cache_entry_t *curr_entry = this->head;
while (curr_entry != NULL)
{
cache_entry_t *old_entry = curr_entry;
curr_entry = old_entry->next;
fz_drop_display_list(mu_ctx, old_entry->dlist);
delete old_entry;
}
this->size = 0;
this->head = NULL;
this->tail = NULL;
}
}
void Cache::Add(int value, int width_in, int height_in, fz_display_list *dlist,
fz_context *mu_ctx)
{
std::lock_guard<std::mutex> lock(cache_lock);
/* If full, then delete the tail */
if (size >= MAX_DISPLAY_CACHE_SIZE)
{
cache_entry_t *curr_entry = this->tail;
cache_entry_t *prev_entry = curr_entry->prev;
if (prev_entry != NULL)
prev_entry->next = NULL;
else
head = NULL;
tail = prev_entry;
/* Decrement the caches rc of this list. It is gone from cache but
may still be in use by other threads, when threads are done they
should decrement and it should be freed at that time. See
ReleaseDisplayLists in muctx class */
fz_drop_display_list(mu_ctx, curr_entry->dlist);
delete curr_entry;
size--;
}
/* Make a new entry and stick at head */
cache_entry_t *new_entry = new cache_entry_t;
new_entry->dlist = dlist;
new_entry->index = value;
new_entry->width = width_in;
new_entry->height = height_in;
new_entry->prev = NULL;
if (head == NULL)
{
new_entry->next = NULL;
head = new_entry;
tail = new_entry;
}
else
{
new_entry->next = head;
head->prev = new_entry;
head = new_entry;
}
size++;
/* Everytime we add an entry, we are also using it. Increment rc. See above */
fz_keep_display_list(mu_ctx, dlist);
}
fz_display_list* Cache::Use(int value, int *width_out, int *height_out, fz_context *mu_ctx)
{
std::lock_guard<std::mutex> lock(cache_lock);
cache_entry_t *curr_entry = this->head;
while (curr_entry != NULL)
{
if (curr_entry->index == value)
break;
curr_entry = curr_entry->next;
}
if (curr_entry != NULL)
{
/* Move this to the front */
if (curr_entry != head)
{
cache_entry_t *prev_entry = curr_entry->prev;
cache_entry_t *next_entry = curr_entry->next;
prev_entry->next = next_entry;
if (next_entry != NULL)
next_entry->prev = prev_entry;
else
tail = prev_entry;
curr_entry->prev = NULL;
curr_entry->next = head;
head->prev = curr_entry;
head = curr_entry;
}
*width_out = curr_entry->width;
*height_out = curr_entry->height;
/* We must increment our reference to this one to ensure it is not
freed when removed from the cache. See above comments */
fz_keep_display_list(mu_ctx, curr_entry->dlist);
return curr_entry->dlist;
}
else
return NULL;
}
|