diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2017-01-01 22:15:24 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2017-01-02 18:53:56 +0900 |
commit | 9e01cf2698d5b24f440d696fd57d469cdc5a6b5f (patch) | |
tree | 63d213239f7bc70c0e8a850e5271ffd259ae6ac0 /src/lib/evas/common | |
parent | b0530aba4f777352cc3ae9772fb1d22f598679a5 (diff) |
evas image async preload - add option to also make header load async
to date if you use async preload we still load the header
synchronously and this can be horrible especially with generic
loaders. there is no way to farm this off to the preload thread. now
there is. youhave to set it as a skip head load option before doing a
file_set AND you need to issue a preload ... but now it's possible.
@feature
Diffstat (limited to 'src/lib/evas/common')
-rw-r--r-- | src/lib/evas/common/evas_image_load.c | 181 |
1 files changed, 111 insertions, 70 deletions
diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c index 0d0261510e..f51ab01309 100644 --- a/src/lib/evas/common/evas_image_load.c +++ b/src/lib/evas/common/evas_image_load.c | |||
@@ -21,7 +21,7 @@ struct ext_loader_s | |||
21 | }; | 21 | }; |
22 | 22 | ||
23 | #define MATCHING(Ext, Module) \ | 23 | #define MATCHING(Ext, Module) \ |
24 | { sizeof (Ext), Ext, Module } | 24 | { sizeof (Ext), Ext, Module } |
25 | 25 | ||
26 | static const struct ext_loader_s loaders[] = | 26 | static const struct ext_loader_s loaders[] = |
27 | { /* map extensions to loaders to use for good first-guess tries */ | 27 | { /* map extensions to loaders to use for good first-guess tries */ |
@@ -181,7 +181,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) | |||
181 | { | 181 | { |
182 | Evas_Image_Load_Func *evas_image_load_func = NULL; | 182 | Evas_Image_Load_Func *evas_image_load_func = NULL; |
183 | Eina_Bool r = EINA_TRUE; | 183 | Eina_Bool r = EINA_TRUE; |
184 | 184 | ||
185 | if (!evas_module_load(em)) goto load_error; | 185 | if (!evas_module_load(em)) goto load_error; |
186 | evas_image_load_func = em->functions; | 186 | evas_image_load_func = em->functions; |
187 | evas_module_use(em); | 187 | evas_module_use(em); |
@@ -196,24 +196,19 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) | |||
196 | ie->f = eina_file_open(ie->file, EINA_FALSE); | 196 | ie->f = eina_file_open(ie->file, EINA_FALSE); |
197 | file = ie->file; | 197 | file = ie->file; |
198 | } | 198 | } |
199 | else | 199 | else file = eina_file_filename_get(ie->f); |
200 | { | 200 | |
201 | file = eina_file_filename_get(ie->f); | ||
202 | } | ||
203 | if (!ie->f) | 201 | if (!ie->f) |
204 | { | 202 | { |
205 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; | 203 | *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; |
206 | goto load_error; | 204 | goto load_error; |
207 | } | 205 | } |
208 | 206 | ||
209 | ie->loader_data = evas_image_load_func->file_open(ie->f, ie->key, | 207 | ie->loader_data = evas_image_load_func->file_open(ie->f, ie->key, |
210 | &ie->load_opts, | 208 | &ie->load_opts, |
211 | &ie->animated, | 209 | &ie->animated, |
212 | error); | 210 | error); |
213 | if (!ie->loader_data) | 211 | if (!ie->loader_data) goto load_error; |
214 | { | ||
215 | goto load_error; | ||
216 | } | ||
217 | 212 | ||
218 | memset(&property, 0, sizeof (property)); | 213 | memset(&property, 0, sizeof (property)); |
219 | if (evas_image_load_func->file_head(ie->loader_data, &property, | 214 | if (evas_image_load_func->file_head(ie->loader_data, &property, |
@@ -231,8 +226,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) | |||
231 | ie->borders.b = property.borders.b; | 226 | ie->borders.b = property.borders.b; |
232 | ie->scale = property.scale; | 227 | ie->scale = property.scale; |
233 | ie->flags.alpha = property.alpha; | 228 | ie->flags.alpha = property.alpha; |
234 | if (property.cspaces) | 229 | if (property.cspaces) ie->cspaces = property.cspaces; |
235 | ie->cspaces = property.cspaces; | ||
236 | ie->flags.rotated = property.rotated; | 230 | ie->flags.rotated = property.rotated; |
237 | ie->flags.flipped = property.flipped; | 231 | ie->flags.flipped = property.flipped; |
238 | r = EINA_FALSE; | 232 | r = EINA_FALSE; |
@@ -249,11 +243,10 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error) | |||
249 | } | 243 | } |
250 | else | 244 | else |
251 | { | 245 | { |
252 | load_error: | 246 | load_error: |
253 | evas_module_unload(em); | 247 | evas_module_unload(em); |
254 | WRN("failed to load module '%s'.", em->definition->name); | 248 | WRN("failed to load module '%s'.", em->definition->name); |
255 | } | 249 | } |
256 | |||
257 | return r; | 250 | return r; |
258 | } | 251 | } |
259 | 252 | ||
@@ -266,9 +259,7 @@ _evas_image_foreach_loader(const Eina_Hash *hash EINA_UNUSED, const void *key EI | |||
266 | Eina_Bool r; | 259 | Eina_Bool r; |
267 | 260 | ||
268 | r = _evas_image_file_header(em, ie, d->error); | 261 | r = _evas_image_file_header(em, ie, d->error); |
269 | 262 | if (!r) d->em = em; | |
270 | if (!r) | ||
271 | d->em = em; | ||
272 | return r; | 263 | return r; |
273 | } | 264 | } |
274 | 265 | ||
@@ -281,12 +272,14 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) | |||
281 | unsigned int i; | 272 | unsigned int i; |
282 | int len, ret = EVAS_LOAD_ERROR_NONE; | 273 | int len, ret = EVAS_LOAD_ERROR_NONE; |
283 | struct evas_image_foreach_loader_data fdata; | 274 | struct evas_image_foreach_loader_data fdata; |
275 | Eina_Bool skip; | ||
284 | 276 | ||
285 | #ifdef EVAS_CSERVE2 | 277 | #ifdef EVAS_CSERVE2 |
286 | if (evas_cserve2_use_get() && evas_cache2_image_cached(ie)) | 278 | if (evas_cserve2_use_get() && evas_cache2_image_cached(ie)) |
287 | CRI("This function shouldn't be called anymore!"); | 279 | CRI("This function shouldn't be called anymore!"); |
288 | #endif | 280 | #endif |
289 | 281 | ||
282 | skip = ie->load_opts.skip_head; | ||
290 | if (ie->f) | 283 | if (ie->f) |
291 | { | 284 | { |
292 | len = strlen(eina_file_filename_get(ie->f)); | 285 | len = strlen(eina_file_filename_get(ie->f)); |
@@ -295,14 +288,16 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) | |||
295 | } | 288 | } |
296 | else | 289 | else |
297 | { | 290 | { |
298 | struct stat st; | 291 | if (!skip) |
299 | |||
300 | if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode)) | ||
301 | { | 292 | { |
302 | DBG("trying to open directory '%s' !", ie->file); | 293 | struct stat st; |
303 | return EVAS_LOAD_ERROR_DOES_NOT_EXIST; | ||
304 | } | ||
305 | 294 | ||
295 | if (stat(ie->file, &st) != 0 || S_ISDIR(st.st_mode)) | ||
296 | { | ||
297 | DBG("trying to open directory '%s' !", ie->file); | ||
298 | return EVAS_LOAD_ERROR_DOES_NOT_EXIST; | ||
299 | } | ||
300 | } | ||
306 | len = strlen(ie->file); | 301 | len = strlen(ie->file); |
307 | end = ie->file + len; | 302 | end = ie->file + len; |
308 | file = ie->file; | 303 | file = ie->file; |
@@ -323,15 +318,19 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) | |||
323 | 318 | ||
324 | if (loader) | 319 | if (loader) |
325 | { | 320 | { |
326 | em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader); | 321 | em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader); |
327 | if (em) | 322 | if (em) |
328 | { | 323 | { |
329 | DBG("found image loader '%s' (%p)", loader, em); | 324 | if (!((Evas_Image_Load_Func *)em->functions)->threadable) |
330 | if (!_evas_image_file_header(em, ie, &ret)) | 325 | skip = EINA_FALSE; |
331 | goto end; | 326 | DBG("found image loader '%s' (%p)", loader, em); |
332 | } | 327 | if (!skip) |
333 | else | 328 | { |
334 | INF("image loader '%s' is not enabled or missing!", loader); | 329 | if (!_evas_image_file_header(em, ie, &ret)) goto end; |
330 | } | ||
331 | } | ||
332 | else INF("image loader '%s' is not enabled or missing!", loader); | ||
333 | if (skip) goto end; | ||
335 | } | 334 | } |
336 | 335 | ||
337 | fdata.ie = ie; | 336 | fdata.ie = ie; |
@@ -346,38 +345,37 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) | |||
346 | /* FIXME: We could use eina recursive module search ability. */ | 345 | /* FIXME: We could use eina recursive module search ability. */ |
347 | for (i = 0; i < sizeof (loaders_name) / sizeof (char *); i++) | 346 | for (i = 0; i < sizeof (loaders_name) / sizeof (char *); i++) |
348 | { | 347 | { |
349 | em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loaders_name[i]); | 348 | em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loaders_name[i]); |
350 | if (em) | 349 | if (em) |
351 | { | 350 | { |
352 | if (!_evas_image_file_header(em, ie, &ret)) | 351 | if (!ie->load_opts.skip_head) |
353 | goto end; | 352 | { |
354 | } | 353 | if (!_evas_image_file_header(em, ie, &ret)) goto end; |
355 | else | 354 | } |
356 | DBG("could not find module '%s'", loaders_name[i]); | 355 | } |
356 | else | ||
357 | DBG("could not find module '%s'", loaders_name[i]); | ||
357 | } | 358 | } |
358 | |||
359 | INF("exhausted all means to load image '%s'", file); | 359 | INF("exhausted all means to load image '%s'", file); |
360 | return EVAS_LOAD_ERROR_UNKNOWN_FORMAT; | 360 | return EVAS_LOAD_ERROR_UNKNOWN_FORMAT; |
361 | 361 | ||
362 | end: | ||
363 | |||
364 | if (ret != EVAS_LOAD_ERROR_NONE) | 362 | if (ret != EVAS_LOAD_ERROR_NONE) |
365 | { | 363 | { |
366 | const char *modname = NULL; | 364 | const char *modname = NULL; |
367 | int modversion = -1; | 365 | int modversion = -1; |
368 | if (em && em->definition) | ||
369 | { | ||
370 | modname = em->definition->name; | ||
371 | modversion = em->definition->version; | ||
372 | } | ||
373 | WRN("loader '%s' (version %d) " | ||
374 | "handled file '%s', key '%s' with errors: %s", | ||
375 | modname ? modname : "<UNKNOWN>", modversion, | ||
376 | file, ie->key ? ie->key : "", | ||
377 | evas_load_error_str(ret)); | ||
378 | goto end; | ||
379 | } | ||
380 | 366 | ||
367 | if (em && em->definition) | ||
368 | { | ||
369 | modname = em->definition->name; | ||
370 | modversion = em->definition->version; | ||
371 | } | ||
372 | WRN("loader '%s' (version %d) " | ||
373 | "handled file '%s', key '%s' with errors: %s", | ||
374 | modname ? modname : "<UNKNOWN>", modversion, | ||
375 | file, ie->key ? ie->key : "", | ||
376 | evas_load_error_str(ret)); | ||
377 | } | ||
378 | end: | ||
381 | DBG("loader '%s' used for file %s", | 379 | DBG("loader '%s' used for file %s", |
382 | (em && em->definition && em->definition->name) ? | 380 | (em && em->definition && em->definition->name) ? |
383 | em->definition->name : "<UNKNOWN>", | 381 | em->definition->name : "<UNKNOWN>", |
@@ -389,6 +387,21 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie) | |||
389 | return ret; | 387 | return ret; |
390 | } | 388 | } |
391 | 389 | ||
390 | static void | ||
391 | _timestamp_build(Image_Timestamp *tstamp, struct stat *st) | ||
392 | { | ||
393 | tstamp->mtime = st->st_mtime; | ||
394 | tstamp->size = st->st_size; | ||
395 | tstamp->ino = st->st_ino; | ||
396 | #ifdef _STAT_VER_LINUX | ||
397 | # if (defined __USE_MISC && defined st_mtime) | ||
398 | tstamp->mtime_nsec = (unsigned long int)st->st_mtim.tv_nsec; | ||
399 | # else | ||
400 | tstamp->mtime_nsec = (unsigned long int)st->st_mtimensec; | ||
401 | # endif | ||
402 | #endif | ||
403 | } | ||
404 | |||
392 | EAPI int | 405 | EAPI int |
393 | evas_common_load_rgba_image_data_from_file(Image_Entry *ie) | 406 | evas_common_load_rgba_image_data_from_file(Image_Entry *ie) |
394 | { | 407 | { |
@@ -396,6 +409,8 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie) | |||
396 | Evas_Image_Load_Func *evas_image_load_func = NULL; | 409 | Evas_Image_Load_Func *evas_image_load_func = NULL; |
397 | Evas_Image_Property property; | 410 | Evas_Image_Property property; |
398 | int ret = EVAS_LOAD_ERROR_NONE; | 411 | int ret = EVAS_LOAD_ERROR_NONE; |
412 | struct stat st; | ||
413 | unsigned int i; | ||
399 | 414 | ||
400 | if ((ie->flags.loaded) && (!ie->animated.animated)) return EVAS_LOAD_ERROR_GENERIC; | 415 | if ((ie->flags.loaded) && (!ie->animated.animated)) return EVAS_LOAD_ERROR_GENERIC; |
401 | 416 | ||
@@ -406,12 +421,44 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie) | |||
406 | 421 | ||
407 | if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC; | 422 | if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC; |
408 | 423 | ||
409 | // printf("load data [%p] %s %s\n", ie, ie->file, ie->key); | ||
410 | evas_image_load_func = ie->info.loader; | 424 | evas_image_load_func = ie->info.loader; |
411 | evas_module_use(ie->info.module); | 425 | evas_module_use(ie->info.module); |
412 | 426 | ||
427 | if (!ie->f) | ||
428 | { | ||
429 | Evas_Module *em = ie->info.module; | ||
430 | |||
431 | if (_evas_image_file_header(em, ie, &ret)) | ||
432 | { | ||
433 | em = NULL; | ||
434 | for (i = 0; i < sizeof(loaders_name) / sizeof (char *); i++) | ||
435 | { | ||
436 | em = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, | ||
437 | loaders_name[i]); | ||
438 | if (em) | ||
439 | { | ||
440 | if (!ie->load_opts.skip_head) | ||
441 | { | ||
442 | if (!_evas_image_file_header(em, ie, &ret)) | ||
443 | goto end; | ||
444 | } | ||
445 | } | ||
446 | else DBG("could not find module '%s'", loaders_name[i]); | ||
447 | em = NULL; | ||
448 | } | ||
449 | } | ||
450 | end: | ||
451 | if (ie->info.module != em) | ||
452 | { | ||
453 | evas_module_ref(em); | ||
454 | evas_module_unref(ie->info.module); | ||
455 | ie->info.module = em; | ||
456 | } | ||
457 | } | ||
413 | if (!ie->f) return EVAS_LOAD_ERROR_DOES_NOT_EXIST; | 458 | if (!ie->f) return EVAS_LOAD_ERROR_DOES_NOT_EXIST; |
414 | 459 | ||
460 | if (stat(ie->file, &st) == 0) _timestamp_build(&(ie->tstamp), &st); | ||
461 | |||
415 | memset(&property, 0, sizeof (property)); | 462 | memset(&property, 0, sizeof (property)); |
416 | property.w = ie->w; | 463 | property.w = ie->w; |
417 | property.h = ie->h; | 464 | property.h = ie->h; |
@@ -429,17 +476,13 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie) | |||
429 | property.borders.b = ie->borders.b; | 476 | property.borders.b = ie->borders.b; |
430 | 477 | ||
431 | pixels = evas_cache_image_pixels(ie); | 478 | pixels = evas_cache_image_pixels(ie); |
432 | if (!pixels) | 479 | if (!pixels) return EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; |
433 | return EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | ||
434 | 480 | ||
435 | evas_image_load_func->file_data(ie->loader_data, &property, pixels, &ret); | 481 | evas_image_load_func->file_data(ie->loader_data, &property, pixels, &ret); |
436 | 482 | ||
437 | ie->flags.alpha_sparse = property.alpha_sparse; | 483 | ie->flags.alpha_sparse = property.alpha_sparse; |
438 | 484 | ||
439 | if (property.premul) | 485 | if (property.premul) evas_common_image_premul(ie); |
440 | evas_common_image_premul(ie); | ||
441 | // evas_module_unref(ie->info.module); | ||
442 | // ie->info.module = NULL; | ||
443 | 486 | ||
444 | return ret; | 487 | return ret; |
445 | } | 488 | } |
@@ -456,7 +499,6 @@ evas_common_load_rgba_image_frame_duration_from_file(Image_Entry *ie, const int | |||
456 | if (evas_image_load_func->frame_duration) | 499 | if (evas_image_load_func->frame_duration) |
457 | { | 500 | { |
458 | if (!ie->f) return -1; | 501 | if (!ie->f) return -1; |
459 | |||
460 | return evas_image_load_func->frame_duration(ie->loader_data, start, frame_num); | 502 | return evas_image_load_func->frame_duration(ie->loader_data, start, frame_num); |
461 | } | 503 | } |
462 | return -1; | 504 | return -1; |
@@ -478,6 +520,5 @@ evas_common_extension_can_load_get(const char *file) | |||
478 | if (!strcasecmp(loaders[i].extension, file + length - loaders[i].length)) | 520 | if (!strcasecmp(loaders[i].extension, file + length - loaders[i].length)) |
479 | return EINA_TRUE; | 521 | return EINA_TRUE; |
480 | } | 522 | } |
481 | |||
482 | return EINA_FALSE; | 523 | return EINA_FALSE; |
483 | } | 524 | } |