summaryrefslogtreecommitdiff
path: root/src/lib/evas/common
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-01-01 22:15:24 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-01-02 18:53:56 +0900
commit9e01cf2698d5b24f440d696fd57d469cdc5a6b5f (patch)
tree63d213239f7bc70c0e8a850e5271ffd259ae6ac0 /src/lib/evas/common
parentb0530aba4f777352cc3ae9772fb1d22f598679a5 (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.c181
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
26static const struct ext_loader_s loaders[] = 26static 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: 246load_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 }
378end:
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
390static 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
392EAPI int 405EAPI int
393evas_common_load_rgba_image_data_from_file(Image_Entry *ie) 406evas_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 }
450end:
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}