File: | content/handlers/image/image_cache.c |
Warning: | line 449, column 3 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2011 Vincent Sanders <vince@netsurf-browser.org> | |||
3 | * | |||
4 | * This file is part of NetSurf, http://www.netsurf-browser.org/ | |||
5 | * | |||
6 | * NetSurf is free software; you can redistribute it and/or modify | |||
7 | * it under the terms of the GNU General Public License as published by | |||
8 | * the Free Software Foundation; version 2 of the License. | |||
9 | * | |||
10 | * NetSurf is distributed in the hope that it will be useful, | |||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
13 | * GNU General Public License for more details. | |||
14 | * | |||
15 | * You should have received a copy of the GNU General Public License | |||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
17 | */ | |||
18 | ||||
19 | /** | |||
20 | * \file | |||
21 | * Cache implementation for bitmap images decoded into frontend format. | |||
22 | */ | |||
23 | ||||
24 | #include <assert.h> | |||
25 | #include <stdint.h> | |||
26 | #include <stdbool.h> | |||
27 | #include <string.h> | |||
28 | #include <stdlib.h> | |||
29 | ||||
30 | #include "netsurf/inttypes.h" | |||
31 | #include "utils/utils.h" | |||
32 | #include "utils/log.h" | |||
33 | #include "netsurf/misc.h" | |||
34 | #include "netsurf/bitmap.h" | |||
35 | #include "content/llcache.h" | |||
36 | #include "content/content_protected.h" | |||
37 | #include "desktop/gui_internal.h" | |||
38 | ||||
39 | #include "image/image_cache.h" | |||
40 | #include "image/image.h" | |||
41 | ||||
42 | /** | |||
43 | * Age of an entry within the cache | |||
44 | * | |||
45 | * type deffed away so it can be readily changed later perhaps to a | |||
46 | * wallclock time structure. | |||
47 | */ | |||
48 | typedef unsigned int cache_age; | |||
49 | ||||
50 | /** | |||
51 | * Image cache entry | |||
52 | */ | |||
53 | struct image_cache_entry_s { | |||
54 | struct image_cache_entry_s *next; /**< next cache entry in list */ | |||
55 | struct image_cache_entry_s *prev; /**< previous cache entry in list */ | |||
56 | ||||
57 | /** content is used as a key */ | |||
58 | struct content *content; | |||
59 | /** associated bitmap entry */ | |||
60 | struct bitmap *bitmap; | |||
61 | /** routine to convert content into bitmap */ | |||
62 | image_cache_convert_fn *convert; | |||
63 | ||||
64 | /* Statistics for replacement algorithm */ | |||
65 | ||||
66 | unsigned int redraw_count; /**< number of times object has been drawn */ | |||
67 | cache_age redraw_age; /**< Age of last redraw */ | |||
68 | size_t bitmap_size; /**< size if storage occupied by bitmap */ | |||
69 | cache_age bitmap_age; /**< Age of last conversion to a bitmap by cache*/ | |||
70 | ||||
71 | int conversion_count; /**< Number of times image has been converted */ | |||
72 | }; | |||
73 | ||||
74 | /** | |||
75 | * Current state of the cache. | |||
76 | * | |||
77 | * Global state of the cache. entries "age" is determined based on a | |||
78 | * monotonically incrementing operation count. This avoids issues with | |||
79 | * using wall clock time while allowing the LRU algorithm to work | |||
80 | * sensibly. | |||
81 | */ | |||
82 | struct image_cache_s { | |||
83 | /** Cache parameters */ | |||
84 | struct image_cache_parameters params; | |||
85 | ||||
86 | /** The "age" of the current operation */ | |||
87 | cache_age current_age; | |||
88 | ||||
89 | /* The objects the cache holds */ | |||
90 | struct image_cache_entry_s *entries; | |||
91 | ||||
92 | ||||
93 | /* Statistics for management algorithm */ | |||
94 | ||||
95 | /** total size of bitmaps currently allocated */ | |||
96 | size_t total_bitmap_size; | |||
97 | ||||
98 | /** Total count of bitmaps currently allocated */ | |||
99 | int bitmap_count; | |||
100 | ||||
101 | /** Maximum size of bitmaps allocated at any one time */ | |||
102 | size_t max_bitmap_size; | |||
103 | /** The number of objects when maximum bitmap usage occurred */ | |||
104 | int max_bitmap_size_count; | |||
105 | ||||
106 | /** Maximum count of bitmaps allocated at any one time */ | |||
107 | int max_bitmap_count; | |||
108 | /** The size of the bitmaps when the max count occurred */ | |||
109 | size_t max_bitmap_count_size; | |||
110 | ||||
111 | /** Bitmap was not available at plot time required conversion */ | |||
112 | int miss_count; | |||
113 | uint64_t miss_size; | |||
114 | /** Bitmap was available at plot time required no conversion */ | |||
115 | int hit_count; | |||
116 | uint64_t hit_size; | |||
117 | /** Bitmap was not available at plot time and required | |||
118 | * conversion which failed. | |||
119 | */ | |||
120 | int fail_count; | |||
121 | uint64_t fail_size; | |||
122 | ||||
123 | /* Cache entry freed without ever being redrawn */ | |||
124 | int total_unrendered; | |||
125 | /** Bitmap was available but never required - wasted conversions */ | |||
126 | int specultive_miss_count; | |||
127 | ||||
128 | /** Total number of additional (after the first) conversions */ | |||
129 | int total_extra_conversions; | |||
130 | /** counts total number of images with more than one conversion */ | |||
131 | int total_extra_conversions_count; | |||
132 | ||||
133 | /** Bitmap with most conversions was converted this many times */ | |||
134 | int peak_conversions; | |||
135 | /** Size of bitmap with most conversions */ | |||
136 | unsigned int peak_conversions_size; | |||
137 | }; | |||
138 | ||||
139 | /** image cache state */ | |||
140 | static struct image_cache_s *image_cache = NULL((void*)0); | |||
141 | ||||
142 | ||||
143 | /** | |||
144 | * Find a cache entry by index. | |||
145 | * | |||
146 | * \param entryn index of cache entry | |||
147 | * \return cache entry at index or NULL if not found. | |||
148 | */ | |||
149 | static struct image_cache_entry_s *image_cache__findn(int entryn) | |||
150 | { | |||
151 | struct image_cache_entry_s *found; | |||
152 | ||||
153 | found = image_cache->entries; | |||
154 | while ((found != NULL((void*)0)) && (entryn > 0)) { | |||
155 | entryn--; | |||
156 | found = found->next; | |||
157 | } | |||
158 | return found; | |||
159 | } | |||
160 | ||||
161 | ||||
162 | /** | |||
163 | * Find the cache entry for a content | |||
164 | * | |||
165 | * \param c The content to get an entry for | |||
166 | * \return The image cache entry or NULL if not found. | |||
167 | */ | |||
168 | static struct image_cache_entry_s *image_cache__find(const struct content *c) | |||
169 | { | |||
170 | struct image_cache_entry_s *found; | |||
171 | ||||
172 | found = image_cache->entries; | |||
173 | while ((found != NULL((void*)0)) && (found->content != c)) { | |||
174 | found = found->next; | |||
175 | } | |||
176 | return found; | |||
177 | } | |||
178 | ||||
179 | /** | |||
180 | * Update the image cache statistics with an entry. | |||
181 | * | |||
182 | * \param centry The image cache entry to update the stats with. | |||
183 | */ | |||
184 | static void image_cache_stats_bitmap_add(struct image_cache_entry_s *centry) | |||
185 | { | |||
186 | centry->bitmap_age = image_cache->current_age; | |||
187 | centry->conversion_count++; | |||
188 | ||||
189 | image_cache->total_bitmap_size += centry->bitmap_size; | |||
190 | image_cache->bitmap_count++; | |||
191 | ||||
192 | if (image_cache->total_bitmap_size > image_cache->max_bitmap_size) { | |||
193 | image_cache->max_bitmap_size = image_cache->total_bitmap_size; | |||
194 | image_cache->max_bitmap_size_count = image_cache->bitmap_count; | |||
195 | ||||
196 | } | |||
197 | ||||
198 | if (image_cache->bitmap_count > image_cache->max_bitmap_count) { | |||
199 | image_cache->max_bitmap_count = image_cache->bitmap_count; | |||
200 | image_cache->max_bitmap_count_size = image_cache->total_bitmap_size; | |||
201 | } | |||
202 | ||||
203 | if (centry->conversion_count == 2) { | |||
204 | image_cache->total_extra_conversions_count++; | |||
205 | } | |||
206 | ||||
207 | if (centry->conversion_count > 1) { | |||
208 | image_cache->total_extra_conversions++; | |||
209 | } | |||
210 | ||||
211 | if ((centry->conversion_count > image_cache->peak_conversions) || | |||
212 | (centry->conversion_count == image_cache->peak_conversions && | |||
213 | centry->bitmap_size > image_cache->peak_conversions_size)) { | |||
214 | image_cache->peak_conversions = centry->conversion_count; | |||
215 | image_cache->peak_conversions_size = centry->bitmap_size; | |||
216 | } | |||
217 | } | |||
218 | ||||
219 | static void image_cache__link(struct image_cache_entry_s *centry) | |||
220 | { | |||
221 | centry->next = image_cache->entries; | |||
222 | centry->prev = NULL((void*)0); | |||
223 | if (centry->next != NULL((void*)0)) { | |||
224 | centry->next->prev = centry; | |||
225 | } | |||
226 | image_cache->entries = centry; | |||
227 | } | |||
228 | ||||
229 | static void image_cache__unlink(struct image_cache_entry_s *centry) | |||
230 | { | |||
231 | /* unlink entry */ | |||
232 | if (centry->prev == NULL((void*)0)) { | |||
233 | /* first in list */ | |||
234 | if (centry->next != NULL((void*)0)) { | |||
235 | centry->next->prev = centry->prev; | |||
236 | image_cache->entries = centry->next; | |||
237 | } else { | |||
238 | /* empty list */ | |||
239 | image_cache->entries = NULL((void*)0); | |||
240 | } | |||
241 | } else { | |||
242 | centry->prev->next = centry->next; | |||
243 | ||||
244 | if (centry->next != NULL((void*)0)) { | |||
245 | centry->next->prev = centry->prev; | |||
246 | } | |||
247 | } | |||
248 | } | |||
249 | ||||
250 | /** | |||
251 | * free bitmap from an image cache entry | |||
252 | * | |||
253 | * \param centry The image cache entry to free bitmap from. | |||
254 | */ | |||
255 | static void image_cache__free_bitmap(struct image_cache_entry_s *centry) | |||
256 | { | |||
257 | if (centry->bitmap != NULL((void*)0)) { | |||
258 | #ifdef IMAGE_CACHE_VERBOSE | |||
259 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 264, }; nslog__log(&_nslog_ctx , "Freeing bitmap %p size %d age %d redraw count %d", centry-> bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); } } while(0 ) | |||
260 | "Freeing bitmap %p size %d age %d redraw count %d",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 264, }; nslog__log(&_nslog_ctx , "Freeing bitmap %p size %d age %d redraw count %d", centry-> bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); } } while(0 ) | |||
261 | centry->bitmap,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 264, }; nslog__log(&_nslog_ctx , "Freeing bitmap %p size %d age %d redraw count %d", centry-> bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); } } while(0 ) | |||
262 | centry->bitmap_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 264, }; nslog__log(&_nslog_ctx , "Freeing bitmap %p size %d age %d redraw count %d", centry-> bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); } } while(0 ) | |||
263 | image_cache->current_age - centry->bitmap_age,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 264, }; nslog__log(&_nslog_ctx , "Freeing bitmap %p size %d age %d redraw count %d", centry-> bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); } } while(0 ) | |||
264 | centry->redraw_count)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 264, }; nslog__log(&_nslog_ctx , "Freeing bitmap %p size %d age %d redraw count %d", centry-> bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count); } } while(0 ); | |||
265 | #endif | |||
266 | guit->bitmap->destroy(centry->bitmap); | |||
267 | centry->bitmap = NULL((void*)0); | |||
268 | image_cache->total_bitmap_size -= centry->bitmap_size; | |||
269 | image_cache->bitmap_count--; | |||
270 | if (centry->redraw_count == 0) { | |||
271 | image_cache->specultive_miss_count++; | |||
272 | } | |||
273 | } | |||
274 | ||||
275 | } | |||
276 | ||||
277 | /** | |||
278 | * free image cache entry | |||
279 | * | |||
280 | * \param centry The image cache entry to free. | |||
281 | */ | |||
282 | static void image_cache__free_entry(struct image_cache_entry_s *centry) | |||
283 | { | |||
284 | #ifdef IMAGE_CACHE_VERBOSE | |||
285 | NSLOG(netsurf, INFO, "freeing %p ", centry)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 285, }; nslog__log(&_nslog_ctx , "freeing %p ", centry); } } while(0); | |||
286 | #endif | |||
287 | ||||
288 | if (centry->redraw_count == 0) { | |||
289 | image_cache->total_unrendered++; | |||
290 | } | |||
291 | ||||
292 | image_cache__free_bitmap(centry); | |||
293 | ||||
294 | image_cache__unlink(centry); | |||
295 | ||||
296 | free(centry); | |||
297 | } | |||
298 | ||||
299 | /** | |||
300 | * Image cache cleaner | |||
301 | * | |||
302 | * \param icache The image cache context. | |||
303 | */ | |||
304 | static void image_cache__clean(struct image_cache_s *icache) | |||
305 | { | |||
306 | struct image_cache_entry_s *centry = icache->entries; | |||
307 | ||||
308 | while (centry != NULL((void*)0)) { | |||
309 | if ((icache->current_age - centry->redraw_age) > | |||
310 | icache->params.bg_clean_time) { | |||
311 | /* only consider older entries, avoids active entries */ | |||
312 | if ((icache->total_bitmap_size > | |||
313 | (icache->params.limit - icache->params.hysteresis)) && | |||
314 | (rand() > (RAND_MAX2147483647 / 2))) { | |||
315 | image_cache__free_bitmap(centry); | |||
316 | } | |||
317 | } | |||
318 | centry=centry->next; | |||
319 | } | |||
320 | } | |||
321 | ||||
322 | /** | |||
323 | * Cache background scheduled callback. | |||
324 | * | |||
325 | * \param p The image cache context. | |||
326 | */ | |||
327 | static void image_cache__background_update(void *p) | |||
328 | { | |||
329 | struct image_cache_s *icache = p; | |||
330 | ||||
331 | /* increment current cache age */ | |||
332 | icache->current_age += icache->params.bg_clean_time; | |||
333 | ||||
334 | #ifdef IMAGE_CACHE_VERBOSE | |||
335 | NSLOG(netsurf, INFO, "Cache age %ds", icache->current_age / 1000)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 335, }; nslog__log(&_nslog_ctx , "Cache age %ds", icache->current_age / 1000); } } while( 0); | |||
336 | #endif | |||
337 | ||||
338 | image_cache__clean(icache); | |||
339 | ||||
340 | guit->misc->schedule(icache->params.bg_clean_time, | |||
341 | image_cache__background_update, | |||
342 | icache); | |||
343 | } | |||
344 | ||||
345 | /* exported interface documented in image_cache.h */ | |||
346 | struct bitmap *image_cache_get_bitmap(const struct content *c) | |||
347 | { | |||
348 | struct image_cache_entry_s *centry; | |||
349 | ||||
350 | centry = image_cache__find(c); | |||
351 | if (centry == NULL((void*)0)) { | |||
352 | return NULL((void*)0); | |||
353 | } | |||
354 | ||||
355 | if (centry->bitmap == NULL((void*)0)) { | |||
356 | if (centry->convert != NULL((void*)0)) { | |||
357 | centry->bitmap = centry->convert(centry->content); | |||
358 | } | |||
359 | ||||
360 | if (centry->bitmap != NULL((void*)0)) { | |||
361 | image_cache_stats_bitmap_add(centry); | |||
362 | image_cache->miss_count++; | |||
363 | image_cache->miss_size += centry->bitmap_size; | |||
364 | } else { | |||
365 | image_cache->fail_count++; | |||
366 | image_cache->fail_size += centry->bitmap_size; | |||
367 | } | |||
368 | } else { | |||
369 | image_cache->hit_count++; | |||
370 | image_cache->hit_size += centry->bitmap_size; | |||
371 | } | |||
372 | ||||
373 | return centry->bitmap; | |||
374 | } | |||
375 | ||||
376 | /* exported interface documented in image_cache.h */ | |||
377 | bool_Bool image_cache_speculate(struct content *c) | |||
378 | { | |||
379 | bool_Bool decision = false0; | |||
380 | ||||
381 | /* If the cache is below its target usage and the bitmap is | |||
382 | * small enough speculate. | |||
383 | */ | |||
384 | if ((image_cache->total_bitmap_size < image_cache->params.limit) && | |||
385 | (c->size <= image_cache->params.speculative_small)) { | |||
386 | #ifdef IMAGE_CACHE_VERBOSE | |||
387 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 390, }; nslog__log(&_nslog_ctx , "content size (%d) is smaller than minimum (%d)", c->size , SPECULATE_SMALL); } } while(0) | |||
388 | "content size (%d) is smaller than minimum (%d)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 390, }; nslog__log(&_nslog_ctx , "content size (%d) is smaller than minimum (%d)", c->size , SPECULATE_SMALL); } } while(0) | |||
389 | c->size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 390, }; nslog__log(&_nslog_ctx , "content size (%d) is smaller than minimum (%d)", c->size , SPECULATE_SMALL); } } while(0) | |||
390 | SPECULATE_SMALL)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 390, }; nslog__log(&_nslog_ctx , "content size (%d) is smaller than minimum (%d)", c->size , SPECULATE_SMALL); } } while(0); | |||
391 | #endif | |||
392 | decision = true1; | |||
393 | } | |||
394 | ||||
395 | #ifdef IMAGE_CACHE_VERBOSE | |||
396 | NSLOG(netsurf, INFO, "returning %d", decision)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 396, }; nslog__log(&_nslog_ctx , "returning %d", decision); } } while(0); | |||
397 | #endif | |||
398 | return decision; | |||
399 | } | |||
400 | ||||
401 | /* exported interface documented in image_cache.h */ | |||
402 | struct bitmap *image_cache_find_bitmap(struct content *c) | |||
403 | { | |||
404 | struct image_cache_entry_s *centry; | |||
405 | ||||
406 | centry = image_cache__find(c); | |||
407 | if (centry == NULL((void*)0)) { | |||
408 | return NULL((void*)0); | |||
409 | } | |||
410 | ||||
411 | return centry->bitmap; | |||
412 | } | |||
413 | ||||
414 | /* exported interface documented in image_cache.h */ | |||
415 | nserror | |||
416 | image_cache_init(const struct image_cache_parameters *image_cache_parameters) | |||
417 | { | |||
418 | image_cache = calloc(1, sizeof(struct image_cache_s)); | |||
419 | if (image_cache == NULL((void*)0)) { | |||
420 | return NSERROR_NOMEM; | |||
421 | } | |||
422 | ||||
423 | image_cache->params = *image_cache_parameters; | |||
424 | ||||
425 | guit->misc->schedule(image_cache->params.bg_clean_time, | |||
426 | image_cache__background_update, | |||
427 | image_cache); | |||
428 | ||||
429 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 432, }; nslog__log(&_nslog_ctx , "Image cache initialised with a limit of %""zu"" hysteresis of %" "zu", image_cache->params.limit, image_cache->params.hysteresis ); } } while(0) | |||
430 | "Image cache initialised with a limit of %"PRIsizet" hysteresis of %"PRIsizet,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 432, }; nslog__log(&_nslog_ctx , "Image cache initialised with a limit of %""zu"" hysteresis of %" "zu", image_cache->params.limit, image_cache->params.hysteresis ); } } while(0) | |||
431 | image_cache->params.limit,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 432, }; nslog__log(&_nslog_ctx , "Image cache initialised with a limit of %""zu"" hysteresis of %" "zu", image_cache->params.limit, image_cache->params.hysteresis ); } } while(0) | |||
432 | image_cache->params.hysteresis)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 432, }; nslog__log(&_nslog_ctx , "Image cache initialised with a limit of %""zu"" hysteresis of %" "zu", image_cache->params.limit, image_cache->params.hysteresis ); } } while(0); | |||
433 | ||||
434 | return NSERROR_OK; | |||
435 | } | |||
436 | ||||
437 | /* exported interface documented in image_cache.h */ | |||
438 | nserror image_cache_fini(void) | |||
439 | { | |||
440 | unsigned int op_count; | |||
441 | uint64_t op_size; | |||
442 | ||||
443 | guit->misc->schedule(-1, image_cache__background_update, image_cache); | |||
444 | ||||
445 | NSLOG(netsurf, INFO, "Size at finish %"PRIsizet" (in %d)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 446, }; nslog__log(&_nslog_ctx , "Size at finish %""zu"" (in %d)", image_cache->total_bitmap_size , image_cache->bitmap_count); } } while(0) | |||
| ||||
446 | image_cache->total_bitmap_size, image_cache->bitmap_count)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 446, }; nslog__log(&_nslog_ctx , "Size at finish %""zu"" (in %d)", image_cache->total_bitmap_size , image_cache->bitmap_count); } } while(0); | |||
447 | ||||
448 | while (image_cache->entries
| |||
449 | image_cache__free_entry(image_cache->entries); | |||
| ||||
450 | } | |||
451 | ||||
452 | op_count = image_cache->hit_count + | |||
453 | image_cache->miss_count + | |||
454 | image_cache->fail_count; | |||
455 | ||||
456 | op_size = image_cache->hit_size + | |||
457 | image_cache->miss_size + | |||
458 | image_cache->fail_size; | |||
459 | ||||
460 | NSLOG(netsurf, INFO, "Age %ds", image_cache->current_age / 1000)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 460, }; nslog__log(&_nslog_ctx , "Age %ds", image_cache->current_age / 1000); } } while(0 ); | |||
461 | NSLOG(netsurf, INFO, "Peak size %"PRIsizet" (in %d)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 463, }; nslog__log(&_nslog_ctx , "Peak size %""zu"" (in %d)", image_cache->max_bitmap_size , image_cache->max_bitmap_size_count); } } while(0) | |||
462 | image_cache->max_bitmap_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 463, }; nslog__log(&_nslog_ctx , "Peak size %""zu"" (in %d)", image_cache->max_bitmap_size , image_cache->max_bitmap_size_count); } } while(0) | |||
463 | image_cache->max_bitmap_size_count)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 463, }; nslog__log(&_nslog_ctx , "Peak size %""zu"" (in %d)", image_cache->max_bitmap_size , image_cache->max_bitmap_size_count); } } while(0); | |||
464 | NSLOG(netsurf, INFO, "Peak image count %d (size %"PRIsizet")",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 466, }; nslog__log(&_nslog_ctx , "Peak image count %d (size %""zu"")", image_cache->max_bitmap_count , image_cache->max_bitmap_count_size); } } while(0) | |||
465 | image_cache->max_bitmap_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 466, }; nslog__log(&_nslog_ctx , "Peak image count %d (size %""zu"")", image_cache->max_bitmap_count , image_cache->max_bitmap_count_size); } } while(0) | |||
466 | image_cache->max_bitmap_count_size)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 466, }; nslog__log(&_nslog_ctx , "Peak image count %d (size %""zu"")", image_cache->max_bitmap_count , image_cache->max_bitmap_count_size); } } while(0); | |||
467 | ||||
468 | if ((op_count > 0) && (op_size >0)) { | |||
469 | ||||
470 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
471 | "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
472 | op_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
473 | image_cache->hit_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
474 | image_cache->miss_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
475 | image_cache->fail_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
476 | (image_cache->hit_count * 100) / op_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
477 | (image_cache->miss_count * 100) / op_count,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0) | |||
478 | (image_cache->fail_count * 100) / op_count)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 478, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (counts) %d/%d/%d/%d (100%%/%d%%/%d%%/%d%%)" , op_count, image_cache->hit_count, image_cache->miss_count , image_cache->fail_count, (image_cache->hit_count * 100 ) / op_count, (image_cache->miss_count * 100) / op_count, ( image_cache->fail_count * 100) / op_count); } } while(0); | |||
479 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
480 | "Cache total/hit/miss/fail (size) %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64" (100%%/%"PRId64"%%/%"PRId64"%%/%"PRId64"%%)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
481 | op_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
482 | image_cache->hit_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
483 | image_cache->miss_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
484 | image_cache->fail_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
485 | (image_cache->hit_size * 100) / op_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
486 | (image_cache->miss_size * 100) / op_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0) | |||
487 | (image_cache->fail_size * 100) / op_size)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 487, }; nslog__log(&_nslog_ctx , "Cache total/hit/miss/fail (size) %""l" "u""/%""l" "u""/%""l" "u""/%""l" "u"" (100%%/%""l" "d""%%/%""l" "d""%%/%""l" "d""%%)" , op_size, image_cache->hit_size, image_cache->miss_size , image_cache->fail_size, (image_cache->hit_size * 100) / op_size, (image_cache->miss_size * 100) / op_size, (image_cache ->fail_size * 100) / op_size); } } while(0); | |||
488 | } | |||
489 | ||||
490 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 493, }; nslog__log(&_nslog_ctx , "Total images never rendered: %d (includes %d that were converted)" , image_cache->total_unrendered, image_cache->specultive_miss_count ); } } while(0) | |||
491 | "Total images never rendered: %d (includes %d that were converted)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 493, }; nslog__log(&_nslog_ctx , "Total images never rendered: %d (includes %d that were converted)" , image_cache->total_unrendered, image_cache->specultive_miss_count ); } } while(0) | |||
492 | image_cache->total_unrendered,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 493, }; nslog__log(&_nslog_ctx , "Total images never rendered: %d (includes %d that were converted)" , image_cache->total_unrendered, image_cache->specultive_miss_count ); } } while(0) | |||
493 | image_cache->specultive_miss_count)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 493, }; nslog__log(&_nslog_ctx , "Total images never rendered: %d (includes %d that were converted)" , image_cache->total_unrendered, image_cache->specultive_miss_count ); } } while(0); | |||
494 | ||||
495 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 498, }; nslog__log(&_nslog_ctx , "Total number of excessive conversions: %d (from %d images converted more than once)" , image_cache->total_extra_conversions, image_cache->total_extra_conversions_count ); } } while(0) | |||
496 | "Total number of excessive conversions: %d (from %d images converted more than once)",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 498, }; nslog__log(&_nslog_ctx , "Total number of excessive conversions: %d (from %d images converted more than once)" , image_cache->total_extra_conversions, image_cache->total_extra_conversions_count ); } } while(0) | |||
497 | image_cache->total_extra_conversions,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 498, }; nslog__log(&_nslog_ctx , "Total number of excessive conversions: %d (from %d images converted more than once)" , image_cache->total_extra_conversions, image_cache->total_extra_conversions_count ); } } while(0) | |||
498 | image_cache->total_extra_conversions_count)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 498, }; nslog__log(&_nslog_ctx , "Total number of excessive conversions: %d (from %d images converted more than once)" , image_cache->total_extra_conversions, image_cache->total_extra_conversions_count ); } } while(0); | |||
499 | ||||
500 | NSLOG(netsurf, INFO, "Bitmap of size %d had most (%d) conversions",do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 502, }; nslog__log(&_nslog_ctx , "Bitmap of size %d had most (%d) conversions", image_cache-> peak_conversions_size, image_cache->peak_conversions); } } while(0) | |||
501 | image_cache->peak_conversions_size,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 502, }; nslog__log(&_nslog_ctx , "Bitmap of size %d had most (%d) conversions", image_cache-> peak_conversions_size, image_cache->peak_conversions); } } while(0) | |||
502 | image_cache->peak_conversions)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 502, }; nslog__log(&_nslog_ctx , "Bitmap of size %d had most (%d) conversions", image_cache-> peak_conversions_size, image_cache->peak_conversions); } } while(0); | |||
503 | ||||
504 | free(image_cache); | |||
505 | ||||
506 | return NSERROR_OK; | |||
507 | } | |||
508 | ||||
509 | /* exported interface documented in image_cache.h */ | |||
510 | nserror image_cache_add(struct content *content, | |||
511 | struct bitmap *bitmap, | |||
512 | image_cache_convert_fn *convert) | |||
513 | { | |||
514 | struct image_cache_entry_s *centry; | |||
515 | ||||
516 | /* bump the cache age by a ms to ensure multiple items are not | |||
517 | * added at exactly the same time | |||
518 | */ | |||
519 | image_cache->current_age++; | |||
520 | ||||
521 | centry = image_cache__find(content); | |||
522 | if (centry == NULL((void*)0)) { | |||
523 | /* new cache entry, content not previously added */ | |||
524 | centry = calloc(1, sizeof(struct image_cache_entry_s)); | |||
525 | if (centry == NULL((void*)0)) { | |||
526 | return NSERROR_NOMEM; | |||
527 | } | |||
528 | image_cache__link(centry); | |||
529 | centry->content = content; | |||
530 | ||||
531 | centry->bitmap_size = content->width * content->height * 4llu; | |||
532 | } | |||
533 | ||||
534 | NSLOG(netsurf, INFO, "centry %p, content %p, bitmap %p", centry,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 535, }; nslog__log(&_nslog_ctx , "centry %p, content %p, bitmap %p", centry, content, bitmap ); } } while(0) | |||
535 | content, bitmap)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 535, }; nslog__log(&_nslog_ctx , "centry %p, content %p, bitmap %p", centry, content, bitmap ); } } while(0); | |||
536 | ||||
537 | centry->convert = convert; | |||
538 | ||||
539 | /* set bitmap entry if one is passed, free extant one if present */ | |||
540 | if (bitmap != NULL((void*)0)) { | |||
541 | if (centry->bitmap != NULL((void*)0)) { | |||
542 | guit->bitmap->destroy(centry->bitmap); | |||
543 | } else { | |||
544 | image_cache_stats_bitmap_add(centry); | |||
545 | } | |||
546 | centry->bitmap = bitmap; | |||
547 | } else { | |||
548 | /* no bitmap, check to see if we should speculatively convert */ | |||
549 | if ((centry->convert != NULL((void*)0)) && | |||
550 | (image_cache_speculate(content) == true1)) { | |||
551 | centry->bitmap = centry->convert(centry->content); | |||
552 | ||||
553 | if (centry->bitmap != NULL((void*)0)) { | |||
554 | image_cache_stats_bitmap_add(centry); | |||
555 | } else { | |||
556 | image_cache->fail_count++; | |||
557 | } | |||
558 | } | |||
559 | } | |||
560 | ||||
561 | ||||
562 | ||||
563 | return NSERROR_OK; | |||
564 | } | |||
565 | ||||
566 | /* exported interface documented in image_cache.h */ | |||
567 | nserror image_cache_remove(struct content *content) | |||
568 | { | |||
569 | struct image_cache_entry_s *centry; | |||
570 | ||||
571 | /* get the cache entry */ | |||
572 | centry = image_cache__find(content); | |||
573 | if (centry == NULL((void*)0)) { | |||
574 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 575, }; nslog__log(&_nslog_ctx , "Could not find cache entry for content (%p)", content); } } while(0) | |||
575 | "Could not find cache entry for content (%p)", content)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 575, }; nslog__log(&_nslog_ctx , "Could not find cache entry for content (%p)", content); } } while(0); | |||
576 | return NSERROR_NOT_FOUND; | |||
577 | } | |||
578 | ||||
579 | image_cache__free_entry(centry); | |||
580 | ||||
581 | return NSERROR_OK; | |||
582 | } | |||
583 | ||||
584 | /* exported interface documented in image_cache.h */ | |||
585 | int image_cache_snsummaryf(char *string, size_t size, const char *fmt) | |||
586 | { | |||
587 | size_t slen = 0; /* current output string length */ | |||
588 | int fmtc = 0; /* current index into format string */ | |||
589 | bool_Bool pct; | |||
590 | unsigned int op_count; | |||
591 | uint64_t op_size; | |||
592 | ||||
593 | op_count = image_cache->hit_count + | |||
594 | image_cache->miss_count + | |||
595 | image_cache->fail_count; | |||
596 | ||||
597 | op_size = image_cache->hit_size + | |||
598 | image_cache->miss_size + | |||
599 | image_cache->fail_size; | |||
600 | ||||
601 | while((slen < size) && (fmt[fmtc] != 0)) { | |||
602 | if (fmt[fmtc] == '%') { | |||
603 | fmtc++; | |||
604 | ||||
605 | /* check for percentage modifier */ | |||
606 | if (fmt[fmtc] == 'p') { | |||
607 | fmtc++; | |||
608 | pct = true1; | |||
609 | } else { | |||
610 | pct = false0; | |||
611 | } | |||
612 | ||||
613 | #define FMTCHR(chr,fmt,var) case chr : \ | |||
614 | slen += snprintf(string + slen, size - slen, "%"fmt, image_cache->var); break | |||
615 | ||||
616 | #define FMTPCHR(chr,fmt,var,div) \ | |||
617 | case chr : \ | |||
618 | if (pct) { \ | |||
619 | if (div > 0) { \ | |||
620 | slen += snprintf(string + slen, size - slen, "%"PRId64"l" "d", (uint64_t)((image_cache->var * 100) / div)); \ | |||
621 | } else { \ | |||
622 | slen += snprintf(string + slen, size - slen, "100"); \ | |||
623 | } \ | |||
624 | } else { \ | |||
625 | slen += snprintf(string + slen, size - slen, "%"fmt, image_cache->var); \ | |||
626 | } break | |||
627 | ||||
628 | ||||
629 | switch (fmt[fmtc]) { | |||
630 | case '%': | |||
631 | string[slen] = '%'; | |||
632 | slen++; | |||
633 | break; | |||
634 | ||||
635 | FMTCHR('a', PRIsizet"zu", params.limit); | |||
636 | FMTCHR('b', PRIsizet"zu", params.hysteresis); | |||
637 | FMTCHR('c', PRIsizet"zu", total_bitmap_size); | |||
638 | FMTCHR('d', "d", bitmap_count); | |||
639 | FMTCHR('e', "u", current_age / 1000); | |||
640 | FMTCHR('f', PRIsizet"zu", max_bitmap_size); | |||
641 | FMTCHR('g', "d", max_bitmap_size_count); | |||
642 | FMTCHR('h', "d", max_bitmap_count); | |||
643 | FMTCHR('i', PRIsizet"zu", max_bitmap_count_size); | |||
644 | ||||
645 | ||||
646 | case 'j': | |||
647 | slen += snprintf(string + slen, size - slen, | |||
648 | "%u", pct?100:op_count); | |||
649 | break; | |||
650 | ||||
651 | FMTPCHR('k', "d", hit_count, op_count); | |||
652 | FMTPCHR('l', "d", miss_count, op_count); | |||
653 | FMTPCHR('m', "d", fail_count, op_count); | |||
654 | ||||
655 | case 'n': | |||
656 | slen += snprintf(string + slen, size - slen, | |||
657 | "%"PRId64"l" "d", pct?100:op_size); | |||
658 | break; | |||
659 | ||||
660 | FMTPCHR('o', PRId64"l" "d", hit_size, op_size); | |||
661 | FMTPCHR('q', PRId64"l" "d", miss_size, op_size); | |||
662 | FMTPCHR('r', PRId64"l" "d", fail_size, op_size); | |||
663 | ||||
664 | FMTCHR('s', "d", total_unrendered); | |||
665 | FMTCHR('t', "d", specultive_miss_count); | |||
666 | FMTCHR('u', "d", total_extra_conversions); | |||
667 | FMTCHR('v', "d", total_extra_conversions_count); | |||
668 | FMTCHR('w', "u", peak_conversions_size); | |||
669 | FMTCHR('x', "d", peak_conversions); | |||
670 | ||||
671 | ||||
672 | } | |||
673 | #undef FMTCHR | |||
674 | #undef FMTPCHR | |||
675 | ||||
676 | fmtc++; | |||
677 | } else { | |||
678 | string[slen] = fmt[fmtc]; | |||
679 | slen++; | |||
680 | fmtc++; | |||
681 | } | |||
682 | } | |||
683 | ||||
684 | /* Ensure that we NUL-terminate the output */ | |||
685 | string[min(slen, size - 1)(((slen)<(size - 1))?(slen):(size - 1))] = '\0'; | |||
686 | ||||
687 | return slen; | |||
688 | } | |||
689 | ||||
690 | /* exported interface documented in image_cache.h */ | |||
691 | int | |||
692 | image_cache_snentryf(char *string, | |||
693 | size_t size, | |||
694 | unsigned int entryn, | |||
695 | const char *fmt) | |||
696 | { | |||
697 | struct image_cache_entry_s *centry; | |||
698 | size_t slen = 0; /* current output string length */ | |||
699 | int fmtc = 0; /* current index into format string */ | |||
700 | lwc_string *origin; /* current entry's origin */ | |||
701 | ||||
702 | centry = image_cache__findn(entryn); | |||
703 | if (centry == NULL((void*)0)) | |||
704 | return -1; | |||
705 | ||||
706 | while((slen < size) && (fmt[fmtc] != 0)) { | |||
707 | if (fmt[fmtc] == '%') { | |||
708 | fmtc++; | |||
709 | switch (fmt[fmtc]) { | |||
710 | case 'e': | |||
711 | slen += snprintf(string + slen, size - slen, | |||
712 | "%u", entryn); | |||
713 | break; | |||
714 | ||||
715 | case 'r': | |||
716 | slen += snprintf(string + slen, size - slen, | |||
717 | "%u", centry->redraw_count); | |||
718 | break; | |||
719 | ||||
720 | case 'a': | |||
721 | slen += snprintf(string + slen, size - slen, | |||
722 | "%.2f", (float)((image_cache->current_age - centry->redraw_age)) / 1000); | |||
723 | break; | |||
724 | ||||
725 | ||||
726 | case 'c': | |||
727 | slen += snprintf(string + slen, size - slen, | |||
728 | "%d", centry->conversion_count); | |||
729 | break; | |||
730 | ||||
731 | case 'g': | |||
732 | slen += snprintf(string + slen, size - slen, | |||
733 | "%.2f", (float)((image_cache->current_age - centry->bitmap_age)) / 1000); | |||
734 | break; | |||
735 | ||||
736 | case 'k': | |||
737 | slen += snprintf(string + slen, size - slen, | |||
738 | "%p", centry->content); | |||
739 | break; | |||
740 | ||||
741 | case 'U': | |||
742 | slen += snprintf(string + slen, size - slen, | |||
743 | "%s", nsurl_access(llcache_handle_get_url(centry->content->llcache))); | |||
744 | break; | |||
745 | ||||
746 | case 'o': | |||
747 | if (nsurl_has_component(llcache_handle_get_url( | |||
748 | centry->content->llcache), | |||
749 | NSURL_HOST)) { | |||
750 | origin = nsurl_get_component( | |||
751 | llcache_handle_get_url( | |||
752 | centry->content-> | |||
753 | llcache), | |||
754 | NSURL_HOST); | |||
755 | ||||
756 | slen += snprintf(string + slen, | |||
757 | size - slen, "%s", | |||
758 | lwc_string_data(({((origin != ((void*)0)) ? (void) (0) : __assert_fail ("origin != NULL" , "content/handlers/image/image_cache.c", 759, __extension__ __PRETTY_FUNCTION__ )); (const char *)((origin)+1);}) | |||
759 | origin)({((origin != ((void*)0)) ? (void) (0) : __assert_fail ("origin != NULL" , "content/handlers/image/image_cache.c", 759, __extension__ __PRETTY_FUNCTION__ )); (const char *)((origin)+1);})); | |||
760 | ||||
761 | lwc_string_unref(origin){ lwc_string *__lwc_s = (origin); ((__lwc_s != ((void*)0)) ? ( void) (0) : __assert_fail ("__lwc_s != NULL", "content/handlers/image/image_cache.c" , 761, __extension__ __PRETTY_FUNCTION__)); __lwc_s->refcnt --; if ((__lwc_s->refcnt == 0) || ((__lwc_s->refcnt == 1 ) && (__lwc_s->insensitive == __lwc_s))) lwc_string_destroy (__lwc_s); }; | |||
762 | } else { | |||
763 | slen += snprintf(string + slen, | |||
764 | size - slen, "%s", | |||
765 | "localhost"); | |||
766 | } | |||
767 | break; | |||
768 | ||||
769 | case 's': | |||
770 | if (centry->bitmap != NULL((void*)0)) { | |||
771 | slen += snprintf(string + slen, | |||
772 | size - slen, | |||
773 | "%" PRIsizet"zu", | |||
774 | centry->bitmap_size); | |||
775 | } else { | |||
776 | slen += snprintf(string + slen, | |||
777 | size - slen, | |||
778 | "0"); | |||
779 | } | |||
780 | break; | |||
781 | } | |||
782 | fmtc++; | |||
783 | } else { | |||
784 | string[slen] = fmt[fmtc]; | |||
785 | slen++; | |||
786 | fmtc++; | |||
787 | } | |||
788 | } | |||
789 | ||||
790 | /* Ensure that we NUL-terminate the output */ | |||
791 | string[min(slen, size - 1)(((slen)<(size - 1))?(slen):(size - 1))] = '\0'; | |||
792 | ||||
793 | return slen; | |||
794 | } | |||
795 | ||||
796 | ||||
797 | /* exported interface documented in image_cache.h */ | |||
798 | bool_Bool image_cache_redraw(struct content *c, | |||
799 | struct content_redraw_data *data, | |||
800 | const struct rect *clip, | |||
801 | const struct redraw_context *ctx) | |||
802 | { | |||
803 | struct image_cache_entry_s *centry; | |||
804 | ||||
805 | /* get the cache entry */ | |||
806 | centry = image_cache__find(c); | |||
807 | if (centry == NULL((void*)0)) { | |||
808 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 809, }; nslog__log(&_nslog_ctx , "Could not find cache entry for content (%p)", c); } } while (0) | |||
809 | "Could not find cache entry for content (%p)", c)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 809, }; nslog__log(&_nslog_ctx , "Could not find cache entry for content (%p)", c); } } while (0); | |||
810 | return false0; | |||
811 | } | |||
812 | ||||
813 | if (centry->bitmap == NULL((void*)0)) { | |||
814 | if (centry->convert != NULL((void*)0)) { | |||
815 | centry->bitmap = centry->convert(centry->content); | |||
816 | } | |||
817 | ||||
818 | if (centry->bitmap != NULL((void*)0)) { | |||
819 | image_cache_stats_bitmap_add(centry); | |||
820 | image_cache->miss_count++; | |||
821 | image_cache->miss_size += centry->bitmap_size; | |||
822 | } else { | |||
823 | image_cache->fail_count++; | |||
824 | image_cache->fail_size += centry->bitmap_size; | |||
825 | return false0; | |||
826 | } | |||
827 | } else { | |||
828 | image_cache->hit_count++; | |||
829 | image_cache->hit_size += centry->bitmap_size; | |||
830 | } | |||
831 | ||||
832 | ||||
833 | /* update statistics */ | |||
834 | centry->redraw_count++; | |||
835 | centry->redraw_age = image_cache->current_age; | |||
836 | ||||
837 | return image_bitmap_plot(centry->bitmap, data, clip, ctx); | |||
838 | } | |||
839 | ||||
840 | /* exported interface documented in image_cache.h */ | |||
841 | void image_cache_destroy(struct content *content) | |||
842 | { | |||
843 | struct image_cache_entry_s *centry; | |||
844 | ||||
845 | /* get the cache entry */ | |||
846 | centry = image_cache__find(content); | |||
847 | if (centry == NULL((void*)0)) { | |||
848 | NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 849, }; nslog__log(&_nslog_ctx , "Could not find cache entry for content (%p)", content); } } while(0) | |||
849 | "Could not find cache entry for content (%p)", content)do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf , NSLOG_LEVEL_INFO, "content/handlers/image/image_cache.c", sizeof ("content/handlers/image/image_cache.c") - 1, __PRETTY_FUNCTION__ , sizeof(__PRETTY_FUNCTION__) - 1, 849, }; nslog__log(&_nslog_ctx , "Could not find cache entry for content (%p)", content); } } while(0); | |||
850 | } else { | |||
851 | image_cache__free_entry(centry); | |||
852 | } | |||
853 | } | |||
854 | ||||
855 | /* exported interface documented in image_cache.h */ | |||
856 | void *image_cache_get_internal(const struct content *c, void *context) | |||
857 | { | |||
858 | return image_cache_get_bitmap(c); | |||
859 | } | |||
860 | ||||
861 | /* exported interface documented in image_cache.h */ | |||
862 | bool_Bool image_cache_is_opaque(struct content *c) | |||
863 | { | |||
864 | struct bitmap *bmp; | |||
865 | bmp = image_cache_get_bitmap(c); | |||
866 | if (bmp != NULL((void*)0)) { | |||
867 | return guit->bitmap->get_opaque(bmp); | |||
868 | } | |||
869 | return false0; | |||
870 | } | |||
871 | ||||
872 | /* exported interface documented in image_cache.h */ | |||
873 | content_type image_cache_content_type(void) | |||
874 | { | |||
875 | return CONTENT_IMAGE; | |||
876 | } |