forked from enlightenment/efl
Evas/cserve2: Merge branch 'devs/jpeg/cserve2'
Improve stability, performance and overall support of evas cserve2. In particular: - Implement shared indexes and memory pools to share cserve's internal state with all clients. Apps can then scan these indexes and avoid waiting for socket responses when loading resources. - Implement crash resiliency in evas. If cserve2 crashes, apps can safely reconnect and continue working as if nothing happened. - Implement support for the GL engine (very basic support so far, "just works"). - Improve performance by reusing the scalecache logic.
This commit is contained in:
commit
7338164468
|
@ -999,7 +999,8 @@ bin/evas/dummy_slave
|
|||
bin_PROGRAMS += \
|
||||
bin/evas/evas_cserve2_client \
|
||||
bin/evas/evas_cserve2_usage \
|
||||
bin/evas/evas_cserve2_debug
|
||||
bin/evas/evas_cserve2_debug \
|
||||
bin/evas/evas_cserve2_shm_debug
|
||||
|
||||
bin_evas_evas_cserve2_SOURCES = \
|
||||
bin/evas/evas_cserve2.h \
|
||||
|
@ -1013,6 +1014,7 @@ bin/evas/evas_cserve2_requests.c \
|
|||
bin/evas/evas_cserve2_fonts.c \
|
||||
bin/evas/evas_cserve2_scale.c \
|
||||
bin/evas/evas_cserve2_main_loop_linux.c \
|
||||
bin/evas/evas_cserve2_index.c \
|
||||
lib/evas/cserve2/evas_cs2_utils.h \
|
||||
lib/evas/cserve2/evas_cs2_utils.c
|
||||
|
||||
|
@ -1055,6 +1057,15 @@ bin_evas_evas_cserve2_debug_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
|||
bin_evas_evas_cserve2_debug_LDADD = @USE_EINA_LIBS@
|
||||
bin_evas_evas_cserve2_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
|
||||
|
||||
bin_evas_evas_cserve2_shm_debug_SOURCES = \
|
||||
bin/evas/evas_cserve2_shm_debug.c
|
||||
bin_evas_evas_cserve2_shm_debug_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_srcdir)/src/lib/evas \
|
||||
-I$(top_srcdir)/src/lib/evas/cserve2 \
|
||||
@EINA_CFLAGS@
|
||||
bin_evas_evas_cserve2_shm_debug_LDADD = @USE_EINA_LIBS@
|
||||
bin_evas_evas_cserve2_shm_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
|
||||
|
||||
bin_evas_evas_cserve2_slave_SOURCES = \
|
||||
bin/evas/evas_cserve2_slave.c \
|
||||
bin/evas/evas_cserve2_utils.c \
|
||||
|
|
|
@ -4,22 +4,54 @@
|
|||
#include <Eina.h>
|
||||
#include "evas_cs2.h"
|
||||
|
||||
#ifndef CSERVE2_LOG_LEVEL
|
||||
#define CSERVE2_LOG_LEVEL 4
|
||||
#endif
|
||||
|
||||
#ifdef CRIT
|
||||
#undef CRIT
|
||||
#endif
|
||||
#if CSERVE2_LOG_LEVEL >= 0
|
||||
#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_cserve2_bin_log_dom, __VA_ARGS__)
|
||||
#else
|
||||
#define CRIT(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#ifdef ERR
|
||||
#undef ERR
|
||||
#endif
|
||||
#if CSERVE2_LOG_LEVEL >= 1
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_bin_log_dom, __VA_ARGS__)
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#else
|
||||
#define ERR(...) do {} while(0)
|
||||
#endif
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_bin_log_dom, __VA_ARGS__)
|
||||
|
||||
#ifdef WRN
|
||||
#undef WRN
|
||||
#endif
|
||||
#if CSERVE2_LOG_LEVEL >= 2
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_bin_log_dom, __VA_ARGS__)
|
||||
#else
|
||||
#define WRN(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#ifdef INF
|
||||
#undef INF
|
||||
#endif
|
||||
#if CSERVE2_LOG_LEVEL >= 3
|
||||
#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_bin_log_dom, __VA_ARGS__)
|
||||
#else
|
||||
#define INF(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#endif
|
||||
#if CSERVE2_LOG_LEVEL >= 4
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_bin_log_dom, __VA_ARGS__)
|
||||
#else
|
||||
#define DBG(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#define DEBUG_LOAD_TIME 1
|
||||
|
||||
|
@ -30,6 +62,8 @@ extern Eina_Prefix *_evas_cserve2_pfx;
|
|||
typedef struct _Slave Slave;
|
||||
typedef struct _Slave_Thread_Data Slave_Thread_Data;
|
||||
typedef struct _Shm_Handle Shm_Handle;
|
||||
typedef struct _Shared_Array Shared_Array;
|
||||
typedef struct _Shared_Mempool Shared_Mempool;
|
||||
|
||||
typedef enum {
|
||||
FD_READ = 1,
|
||||
|
@ -69,8 +103,17 @@ typedef enum {
|
|||
} Slave_Command;
|
||||
|
||||
struct _Slave_Msg_Image_Open {
|
||||
Eina_Bool has_loader_data : 1;
|
||||
// Optionally followed by:
|
||||
struct {
|
||||
struct {
|
||||
unsigned int x, y, w, h;
|
||||
} region;
|
||||
double dpi;
|
||||
unsigned int w, h;
|
||||
int scale_down_by;
|
||||
Eina_Bool orientation;
|
||||
} lo;
|
||||
// const char path[];
|
||||
// const char key[];
|
||||
// const char loader[];
|
||||
};
|
||||
|
||||
|
@ -103,6 +146,7 @@ struct _Slave_Msg_Image_Load {
|
|||
|
||||
struct _Slave_Msg_Image_Loaded {
|
||||
int w, h;
|
||||
Eina_Bool alpha : 1;
|
||||
Eina_Bool alpha_sparse : 1;
|
||||
};
|
||||
|
||||
|
@ -140,14 +184,13 @@ struct _Slave_Msg_Font_Glyphs_Load {
|
|||
unsigned int *glyphs;
|
||||
} glyphs;
|
||||
struct {
|
||||
Shm_Handle *shm;
|
||||
unsigned int usage;
|
||||
unsigned int nglyphs;
|
||||
Shared_Mempool *mempool;
|
||||
} cache;
|
||||
};
|
||||
|
||||
struct _Slave_Msg_Glyph {
|
||||
unsigned int index;
|
||||
unsigned int buffer_id;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
unsigned int rows;
|
||||
|
@ -159,21 +202,13 @@ struct _Slave_Msg_Glyph {
|
|||
|
||||
typedef struct _Slave_Msg_Glyph Slave_Msg_Glyph;
|
||||
|
||||
struct _Slave_Msg_Font_Cache {
|
||||
unsigned int nglyphs;
|
||||
Slave_Msg_Glyph *glyphs;
|
||||
Shm_Handle *shm;
|
||||
unsigned int usage;
|
||||
};
|
||||
|
||||
typedef struct _Slave_Msg_Font_Cache Slave_Msg_Font_Cache;
|
||||
|
||||
struct _Slave_Msg_Font_Glyphs_Loaded {
|
||||
unsigned int ncaches;
|
||||
Shared_Mempool *mempool;
|
||||
unsigned int gl_load_time;
|
||||
unsigned int gl_render_time;
|
||||
unsigned int gl_slave_time;
|
||||
Slave_Msg_Font_Cache **caches;
|
||||
Slave_Msg_Glyph *glyphs;
|
||||
unsigned int nglyphs;
|
||||
};
|
||||
|
||||
typedef struct _Slave_Msg_Font_Load Slave_Msg_Font_Load;
|
||||
|
@ -229,6 +264,7 @@ void cserve2_client_del(Client *client);
|
|||
void cserve2_client_deliver(Client *client);
|
||||
void cserve2_client_error_send(Client *client, unsigned int rid, int error_code);
|
||||
ssize_t cserve2_client_send(Client *client, const void *data, size_t size);
|
||||
void cserve2_index_list_send(int generation_id, const char *strings_index_path, const char *strings_entries_path, const char *files_index_path, const char *images_index_path, const char *fonts_index_path, Client *client);
|
||||
|
||||
Eina_Bool cserve2_fd_watch_add(int fd, Fd_Flags flags, Fd_Watch_Cb cb, const void *data);
|
||||
Eina_Bool cserve2_fd_watch_del(int fd);
|
||||
|
@ -260,15 +296,18 @@ void cserve2_message_handler(int fd, Fd_Flags flags, void *data);
|
|||
void cserve2_shm_init();
|
||||
void cserve2_shm_shutdown();
|
||||
Shm_Handle *cserve2_shm_request(const char *infix, size_t size);
|
||||
Shm_Handle *cserve2_shm_segment_request(Shm_Handle *shm, size_t size);
|
||||
Shm_Handle *cserve2_shm_resize(Shm_Handle *shm, size_t newsize);
|
||||
void cserve2_shm_unref(Shm_Handle *shm);
|
||||
const char *cserve2_shm_name_get(const Shm_Handle *shm);
|
||||
int cserve2_shm_id_get(const Shm_Handle *shm);
|
||||
off_t cserve2_shm_map_offset_get(const Shm_Handle *shm);
|
||||
off_t cserve2_shm_offset_get(const Shm_Handle *shm);
|
||||
size_t cserve2_shm_map_size_get(const Shm_Handle *shm);
|
||||
size_t cserve2_shm_size_get(const Shm_Handle *shm);
|
||||
void *cserve2_shm_map(Shm_Handle *shm);
|
||||
void cserve2_shm_unmap(Shm_Handle *shm);
|
||||
size_t cserve2_shm_size_normalize(size_t size);
|
||||
size_t cserve2_shm_size_normalize(size_t size, size_t align);
|
||||
|
||||
void cserve2_command_run(Client *client, Message_Type type);
|
||||
|
||||
|
@ -279,10 +318,10 @@ void cserve2_cache_init(void);
|
|||
void cserve2_cache_shutdown(void);
|
||||
void cserve2_cache_client_new(Client *client);
|
||||
void cserve2_cache_client_del(Client *client);
|
||||
int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid);
|
||||
int cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid, Evas_Image_Load_Opts *lo);
|
||||
void cserve2_cache_file_close(Client *client, unsigned int client_file_id);
|
||||
int cserve2_cache_image_entry_create(Client *client, int rid, unsigned int file_id, unsigned int image_id, Evas_Image_Load_Opts *opts);
|
||||
void cserve2_rgba_image_scale_do(void *src_data, void *dst_data, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int alpha, int smooth);
|
||||
int cserve2_cache_image_entry_create(Client *client, int rid, unsigned int client_file_id, unsigned int image_id, const Evas_Image_Load_Opts *opts);
|
||||
void cserve2_rgba_image_scale_do(void *src_data, int src_full_w, int src_full_h, void *dst_data, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int alpha, int smooth);
|
||||
void cserve2_cache_image_load(Client *client, unsigned int client_image_id, unsigned int rid);
|
||||
void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid);
|
||||
void cserve2_cache_image_unload(Client *client, unsigned int client_image_id);
|
||||
|
@ -302,6 +341,8 @@ void cserve2_request_cancel(Slave_Request *req, Client *client, Error_Type err);
|
|||
void cserve2_request_cancel_all(Slave_Request *req, Error_Type err);
|
||||
void cserve2_requests_init(void);
|
||||
void cserve2_requests_shutdown(void);
|
||||
void cserve2_request_dependents_drop(Slave_Request *req, Slave_Request_Type type);
|
||||
void cserve2_entry_request_drop(void *data, Slave_Request_Type type);
|
||||
|
||||
void cserve2_font_init(void);
|
||||
void cserve2_font_shutdown(void);
|
||||
|
@ -309,4 +350,57 @@ void *cserve2_font_slave_cb(Slave_Thread_Data *sd, Slave_Command *cmd, const voi
|
|||
void cserve2_font_source_ft_free(void *fontsource);
|
||||
void cserve2_font_ft_free(void *fontinfo);
|
||||
|
||||
// Shared buffers & indexes
|
||||
void cserve2_shared_index_init(void);
|
||||
void cserve2_shared_index_shutdown(void);
|
||||
|
||||
typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *sa,
|
||||
const void *elem,
|
||||
void *user_data);
|
||||
|
||||
// Shared arrays (arrays of fixed size object)
|
||||
Shared_Array *cserve2_shared_array_new(int tag, int generation_id, int elemsize, int initcount);
|
||||
const char *cserve2_shared_array_name_get(Shared_Array *sa);
|
||||
void cserve2_shared_array_del(Shared_Array *sa);
|
||||
int cserve2_shared_array_size_get(Shared_Array *sa);
|
||||
int cserve2_shared_array_count_get(Shared_Array *sa);
|
||||
int cserve2_shared_array_map_size_get(Shared_Array *sa);
|
||||
int cserve2_shared_array_item_size_get(Shared_Array *sa);
|
||||
int cserve2_shared_array_generation_id_get(Shared_Array *sa);
|
||||
int cserve2_shared_array_generation_id_set(Shared_Array *sa, int generation_id);
|
||||
int cserve2_shared_array_size_set(Shared_Array *sa, int newcount);
|
||||
int cserve2_shared_array_item_new(Shared_Array *sa);
|
||||
void *cserve2_shared_array_item_data_get(Shared_Array *sa, int elemid);
|
||||
Shared_Array *cserve2_shared_array_repack(Shared_Array *sa, int generation_id,
|
||||
Shared_Array_Repack_Skip_Cb skip,
|
||||
Eina_Compare_Cb cmp, void *user_data);
|
||||
int cserve2_shared_array_item_find(Shared_Array *sa, void *data,
|
||||
Eina_Compare_Cb cmp);
|
||||
void *cserve2_shared_array_item_data_find(Shared_Array *sa, void *data,
|
||||
Eina_Compare_Cb cmp);
|
||||
int cserve2_shared_array_foreach(Shared_Array *sa, Eina_Each_Cb cb, void *data);
|
||||
|
||||
// Shared buffers and memory pools
|
||||
Shared_Mempool *cserve2_shared_mempool_new(int indextag, int index_elemsize, int generation_id, int initsize);
|
||||
void cserve2_shared_mempool_del(Shared_Mempool *sm);
|
||||
int cserve2_shared_mempool_buffer_new(Shared_Mempool *sm, int size);
|
||||
int cserve2_shared_mempool_buffer_ref(Shared_Mempool *sm, int bufferid);
|
||||
void cserve2_shared_mempool_buffer_del(Shared_Mempool *sm, int bufferid);
|
||||
void *cserve2_shared_mempool_buffer_get(Shared_Mempool *sm, int bufferid);
|
||||
int cserve2_shared_mempool_buffer_offset_get(Shared_Mempool *sm, int bufferid);
|
||||
size_t cserve2_shared_mempool_size_get(Shared_Mempool *sm);
|
||||
const char *cserve2_shared_mempool_name_get(Shared_Mempool *sm);
|
||||
int cserve2_shared_mempool_generation_id_get(Shared_Mempool *sm);
|
||||
int cserve2_shared_mempool_generation_id_set(Shared_Mempool *sm, int generation_id);
|
||||
Shared_Array *cserve2_shared_mempool_index_get(Shared_Mempool *sm);
|
||||
|
||||
// Shared strings
|
||||
const char *cserve2_shared_strings_table_name_get();
|
||||
const char *cserve2_shared_strings_index_name_get();
|
||||
int cserve2_shared_string_add(const char *str);
|
||||
int cserve2_shared_string_ref(int id);
|
||||
void cserve2_shared_string_del(int id);
|
||||
const char *cserve2_shared_string_get(int id);
|
||||
int cserve2_shared_strings_repack(Shared_Array_Repack_Skip_Cb skip, Eina_Compare_Cb cmp);
|
||||
|
||||
#endif /* _EVAS_CSERVE2_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -177,8 +177,6 @@ _debug_msg_send(void)
|
|||
}
|
||||
|
||||
typedef struct _Font_Entry Font_Entry;
|
||||
typedef struct _Cache_Entry Cache_Entry;
|
||||
typedef struct _Glyph_Entry Glyph_Entry;
|
||||
|
||||
struct _Font_Entry
|
||||
{
|
||||
|
@ -188,27 +186,9 @@ struct _Font_Entry
|
|||
unsigned int size;
|
||||
unsigned int dpi;
|
||||
unsigned int unused;
|
||||
Eina_List *caches;
|
||||
};
|
||||
|
||||
struct _Cache_Entry
|
||||
{
|
||||
const char *shmname;
|
||||
unsigned int size;
|
||||
unsigned int usage;
|
||||
Eina_List *glyphs;
|
||||
};
|
||||
|
||||
struct _Glyph_Entry
|
||||
{
|
||||
unsigned int index;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
unsigned int rows;
|
||||
unsigned int width;
|
||||
unsigned int pitch;
|
||||
unsigned int num_grays;
|
||||
unsigned int pixel_mode;
|
||||
char glyph_data_shm[64];
|
||||
char glyph_mempool_shm[64];
|
||||
Eina_List *glyphs; // Glyph_Data
|
||||
};
|
||||
|
||||
#define READIT(_dst, _src) \
|
||||
|
@ -217,57 +197,6 @@ struct _Glyph_Entry
|
|||
_src += sizeof(_dst); \
|
||||
} while(0)
|
||||
|
||||
static Glyph_Entry *
|
||||
_parse_glyph_entry(char **msg)
|
||||
{
|
||||
Glyph_Entry *ge;
|
||||
char *buf = *msg;
|
||||
|
||||
ge = calloc(1, sizeof(*ge));
|
||||
|
||||
READIT(ge->index, buf);
|
||||
READIT(ge->offset, buf);
|
||||
READIT(ge->size, buf);
|
||||
READIT(ge->rows, buf);
|
||||
READIT(ge->width, buf);
|
||||
READIT(ge->pitch, buf);
|
||||
READIT(ge->num_grays, buf);
|
||||
READIT(ge->pixel_mode, buf);
|
||||
|
||||
*msg = buf;
|
||||
|
||||
return ge;
|
||||
}
|
||||
|
||||
static Cache_Entry *
|
||||
_parse_cache_entry(char **msg)
|
||||
{
|
||||
Cache_Entry *ce;
|
||||
char *buf = *msg;
|
||||
unsigned int n;
|
||||
|
||||
ce = calloc(1, sizeof(*ce));
|
||||
|
||||
READIT(n, buf);
|
||||
ce->shmname = eina_stringshare_add_length(buf, n);
|
||||
buf += n;
|
||||
|
||||
READIT(ce->size, buf);
|
||||
READIT(ce->usage, buf);
|
||||
|
||||
READIT(n, buf);
|
||||
while (n--)
|
||||
{
|
||||
Glyph_Entry *ge;
|
||||
ge = _parse_glyph_entry(&buf);
|
||||
ce->glyphs = eina_list_append(ce->glyphs, ge);
|
||||
}
|
||||
|
||||
*msg = buf;
|
||||
|
||||
return ce;
|
||||
}
|
||||
|
||||
static Font_Entry *
|
||||
_parse_font_entry(char **msg)
|
||||
{
|
||||
|
@ -291,12 +220,18 @@ _parse_font_entry(char **msg)
|
|||
READIT(fe->dpi, buf);
|
||||
READIT(fe->unused, buf);
|
||||
|
||||
eina_strlcpy(fe->glyph_data_shm, buf, 64);
|
||||
buf += 64;
|
||||
eina_strlcpy(fe->glyph_mempool_shm, buf, 64);
|
||||
buf += 64;
|
||||
|
||||
READIT(n, buf);
|
||||
while (n--)
|
||||
{
|
||||
Cache_Entry *ce;
|
||||
ce = _parse_cache_entry(&buf);
|
||||
fe->caches = eina_list_append(fe->caches, ce);
|
||||
Glyph_Data *gd = calloc(1, sizeof(Glyph_Data));
|
||||
memcpy(gd, buf, sizeof(Glyph_Data));
|
||||
buf += sizeof(Glyph_Data);
|
||||
fe->glyphs = eina_list_append(fe->glyphs, gd);
|
||||
}
|
||||
|
||||
*msg = buf;
|
||||
|
@ -307,7 +242,7 @@ _parse_font_entry(char **msg)
|
|||
static Eina_List *
|
||||
_debug_msg_read(void)
|
||||
{
|
||||
Msg_Base *msg = NULL;
|
||||
Msg_Font_Debug *msg = NULL;
|
||||
char *buf;
|
||||
int size;
|
||||
unsigned int nfonts;
|
||||
|
@ -317,16 +252,16 @@ _debug_msg_read(void)
|
|||
while (!msg)
|
||||
msg = _server_read(&size);
|
||||
|
||||
if (msg->type != CSERVE2_FONT_DEBUG)
|
||||
if (msg->base.type != CSERVE2_FONT_DEBUG)
|
||||
{
|
||||
ERR("Invalid message received from server."
|
||||
ERR("Invalid message received from server. "
|
||||
"Something went badly wrong.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = (char *)msg + sizeof(*msg);
|
||||
|
||||
READIT(nfonts, buf);
|
||||
nfonts = msg->nfonts;
|
||||
while (nfonts--)
|
||||
{
|
||||
Font_Entry *fe;
|
||||
|
@ -334,34 +269,18 @@ _debug_msg_read(void)
|
|||
fonts = eina_list_append(fonts, fe);
|
||||
}
|
||||
|
||||
printf("Font index table: %s\n", msg->fonts_index_path);
|
||||
printf("Contains %u fonts\n\n", msg->nfonts);
|
||||
return fonts;
|
||||
}
|
||||
|
||||
static void
|
||||
_glyph_entry_free(Glyph_Entry *ge)
|
||||
{
|
||||
free(ge);
|
||||
}
|
||||
|
||||
static void
|
||||
_cache_entry_free(Cache_Entry *ce)
|
||||
{
|
||||
Glyph_Entry *ge;
|
||||
|
||||
EINA_LIST_FREE(ce->glyphs, ge)
|
||||
_glyph_entry_free(ge);
|
||||
|
||||
eina_stringshare_del(ce->shmname);
|
||||
free(ce);
|
||||
}
|
||||
|
||||
static void
|
||||
_font_entry_free(Font_Entry *fe)
|
||||
{
|
||||
Cache_Entry *ce;
|
||||
Glyph_Data *gd;
|
||||
|
||||
EINA_LIST_FREE(fe->caches, ce)
|
||||
_cache_entry_free(ce);
|
||||
EINA_LIST_FREE(fe->glyphs, gd)
|
||||
free(gd);
|
||||
|
||||
eina_stringshare_del(fe->name);
|
||||
eina_stringshare_del(fe->file);
|
||||
|
@ -369,7 +288,7 @@ _font_entry_free(Font_Entry *fe)
|
|||
}
|
||||
|
||||
static void
|
||||
_glyph_entry_print(Glyph_Entry *ge)
|
||||
_glyph_data_print(Glyph_Data *gd)
|
||||
{
|
||||
const char *pxmode[] = {
|
||||
"FT_PIXEL_MODE_NONE",
|
||||
|
@ -380,29 +299,18 @@ _glyph_entry_print(Glyph_Entry *ge)
|
|||
"FT_PIXEL_MODE_LCD",
|
||||
"FT_PIXEL_MODE_LCD_V"
|
||||
};
|
||||
printf("\t\tGLYPH %u offset: %u size: %u %ux%u pitch: %u grays: %u "
|
||||
"pixel mode: %s\n",
|
||||
ge->index, ge->offset, ge->size, ge->width, ge->rows, ge->pitch,
|
||||
ge->num_grays, pxmode[ge->pixel_mode]);
|
||||
}
|
||||
|
||||
static void
|
||||
_cache_entry_print(Cache_Entry *ce)
|
||||
{
|
||||
Eina_List *l;
|
||||
Glyph_Entry *ge;
|
||||
|
||||
printf("\tSHM %s used %u/%u\n", ce->shmname, ce->usage, ce->size);
|
||||
|
||||
EINA_LIST_FOREACH(ce->glyphs, l, ge)
|
||||
_glyph_entry_print(ge);
|
||||
printf(" GLYPH id: %-4u refcount %-2u: index: %-6u offset: %-6u size: %-3u "
|
||||
"%2ux%-3u pitch: %-2u grays: %-3u pixel mode: %s hint: %d\n",
|
||||
gd->id, gd->refcount, gd->index, gd->offset, gd->size,
|
||||
gd->width, gd->rows, gd->pitch,
|
||||
gd->num_grays, pxmode[gd->pixel_mode], gd->hint);
|
||||
}
|
||||
|
||||
static void
|
||||
_font_entry_print(Font_Entry *fe)
|
||||
{
|
||||
Eina_List *l;
|
||||
Cache_Entry *ce;
|
||||
Glyph_Data *gd;
|
||||
|
||||
printf("FONT %s:%s size: %u dpi: %u %s%s%s %s\n",
|
||||
fe->file, fe->name, fe->size, fe->dpi,
|
||||
|
@ -410,18 +318,46 @@ _font_entry_print(Font_Entry *fe)
|
|||
fe->rend_flags & 1 ? "SLANT " : "",
|
||||
fe->rend_flags & 2 ? "WEIGHT" : "",
|
||||
fe->unused ? "(unused)" : "");
|
||||
printf(" Index: %s\n"
|
||||
" Mempool: %s\n"
|
||||
" Glyph count: %u\n",
|
||||
fe->glyph_data_shm, fe->glyph_mempool_shm,
|
||||
eina_list_count(fe->glyphs));
|
||||
|
||||
EINA_LIST_FOREACH(fe->caches, l, ce)
|
||||
_cache_entry_print(ce);
|
||||
EINA_LIST_FOREACH(fe->glyphs, l, gd)
|
||||
_glyph_data_print(gd);
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
_shared_index_print(Msg_Index_List *msg, size_t size)
|
||||
{
|
||||
if (size < sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST)
|
||||
{
|
||||
ERR("Invalid message received from server. "
|
||||
"Something went wrong.");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Printing shared indexes status.\n");
|
||||
printf("===============================\n\n");
|
||||
printf("Generation ID: %-4d\n", msg->generation_id);
|
||||
printf("Strings entries path: %s\n", msg->strings_entries_path);
|
||||
printf("Strings index path: %s\n", msg->strings_index_path);
|
||||
printf("Files index path: %s\n", msg->files_index_path);
|
||||
printf("Images index path: %s\n", msg->images_index_path);
|
||||
printf("Fonts index path: %s\n", msg->fonts_index_path);
|
||||
printf("\n\n\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
Eina_List *fonts;
|
||||
Font_Entry *fe;
|
||||
Msg_Index_List *msg = NULL;
|
||||
int size;
|
||||
|
||||
eina_init();
|
||||
_evas_cserve2_debug_log_dom = eina_log_domain_register
|
||||
|
@ -431,6 +367,11 @@ main(void)
|
|||
ERR("Could not connect to server.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!msg)
|
||||
msg = _server_read(&size);
|
||||
_shared_index_print(msg, size);
|
||||
|
||||
_debug_msg_send();
|
||||
fonts = _debug_msg_read();
|
||||
EINA_LIST_FREE(fonts, fe)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define _EVAS_FONT_SLANT_TAN 0.221694663
|
||||
|
||||
#define CHECK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
#define MIN_GLYPHS 50
|
||||
#define MIN_GLYPHS 100 // 26*2 + a nice margin :)
|
||||
#define MAX_CACHE_SIZE 1 * 1024 * 1024 // 1MB
|
||||
|
||||
#define EVAS_FONT_ROUND_26_6_TO_INT(x) \
|
||||
|
@ -47,7 +47,6 @@ struct _Font_Info
|
|||
int dpi;
|
||||
int max_h;
|
||||
unsigned int runtime_rend;
|
||||
int shmsize;
|
||||
};
|
||||
|
||||
struct _Font_Source_Info
|
||||
|
@ -281,14 +280,6 @@ _font_slave_load(const void *cmddata, void *data EINA_UNUSED)
|
|||
return response;
|
||||
}
|
||||
|
||||
static Shm_Handle *
|
||||
_font_slave_memory_alloc(Font_Info *fi)
|
||||
{
|
||||
Shm_Handle *shm = cserve2_shm_request("font", fi->shmsize);
|
||||
|
||||
return shm;
|
||||
}
|
||||
|
||||
/* This function will load the "index" glyph to the glyph slot of the font.
|
||||
* In order to use or render it, one should access it from the glyph slot,
|
||||
* or get the glyph using FT_Get_Glyph().
|
||||
|
@ -326,43 +317,65 @@ _font_slave_glyph_load(Font_Info *fi, unsigned int idx, unsigned int hint)
|
|||
* given Font Cache.
|
||||
*/
|
||||
static Eina_Bool
|
||||
_font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Cache *c, unsigned int idx)
|
||||
_font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Glyphs_Loaded *response,
|
||||
unsigned int idx)
|
||||
{
|
||||
Font_Source_Info *fsi = fi->fsi;
|
||||
unsigned int glyphsize;
|
||||
char *cachedata = cserve2_shm_map(c->shm);
|
||||
FT_Glyph glyph;
|
||||
FT_BitmapGlyph bglyph;
|
||||
char *data;
|
||||
int buffer_id = 0;
|
||||
|
||||
FT_Get_Glyph(fsi->face->glyph, &glyph);
|
||||
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
|
||||
bglyph = (FT_BitmapGlyph)glyph;
|
||||
|
||||
glyphsize = bglyph->bitmap.pitch * bglyph->bitmap.rows;
|
||||
|
||||
if (c->usage + glyphsize > cserve2_shm_size_get(c->shm))
|
||||
if (!glyphsize)
|
||||
{
|
||||
FT_Done_Glyph(glyph);
|
||||
return EINA_FALSE;
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
memcpy(cachedata + c->usage, bglyph->bitmap.buffer, glyphsize);
|
||||
buffer_id = cserve2_shared_mempool_buffer_new(response->mempool, glyphsize);
|
||||
data = cserve2_shared_mempool_buffer_get(response->mempool, buffer_id);
|
||||
if (!data)
|
||||
{
|
||||
FT_Done_Glyph(glyph);
|
||||
goto on_error;
|
||||
}
|
||||
memcpy(data, bglyph->bitmap.buffer, glyphsize);
|
||||
|
||||
// TODO: Check if we have problems with alignment
|
||||
c->glyphs[c->nglyphs].index = idx;
|
||||
c->glyphs[c->nglyphs].offset = c->usage;
|
||||
c->glyphs[c->nglyphs].size = glyphsize;
|
||||
c->glyphs[c->nglyphs].rows = bglyph->bitmap.rows;
|
||||
c->glyphs[c->nglyphs].width = bglyph->bitmap.width;
|
||||
c->glyphs[c->nglyphs].pitch = bglyph->bitmap.pitch;
|
||||
c->glyphs[c->nglyphs].num_grays = bglyph->bitmap.num_grays;
|
||||
c->glyphs[c->nglyphs].pixel_mode = bglyph->bitmap.pixel_mode;
|
||||
c->usage += glyphsize;
|
||||
c->nglyphs++;
|
||||
response->glyphs[response->nglyphs].index = idx;
|
||||
response->glyphs[response->nglyphs].buffer_id = buffer_id;
|
||||
response->glyphs[response->nglyphs].offset =
|
||||
cserve2_shared_mempool_buffer_offset_get(response->mempool, buffer_id);
|
||||
response->glyphs[response->nglyphs].size = glyphsize;
|
||||
response->glyphs[response->nglyphs].rows = bglyph->bitmap.rows;
|
||||
response->glyphs[response->nglyphs].width = bglyph->bitmap.width;
|
||||
response->glyphs[response->nglyphs].pitch = bglyph->bitmap.pitch;
|
||||
response->glyphs[response->nglyphs].num_grays = bglyph->bitmap.num_grays;
|
||||
response->glyphs[response->nglyphs].pixel_mode = bglyph->bitmap.pixel_mode;
|
||||
response->nglyphs++;
|
||||
|
||||
FT_Done_Glyph(glyph);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
on_error:
|
||||
// Create invalid entry for this index. There will be an empty slot in
|
||||
// the mempool (usually 8 bytes) because we need the Glyph_Data index entry.
|
||||
ERR("Could not load glyph %d. Creating empty invalid entry.", idx);
|
||||
memset(&response->glyphs[response->nglyphs], 0, sizeof(Slave_Msg_Glyph));
|
||||
if (buffer_id > 0)
|
||||
cserve2_shared_mempool_buffer_del(response->mempool, buffer_id);
|
||||
buffer_id = cserve2_shared_mempool_buffer_new(response->mempool, 1);
|
||||
response->glyphs[response->nglyphs].index = idx;
|
||||
response->glyphs[response->nglyphs].buffer_id = buffer_id;
|
||||
response->nglyphs++;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -398,24 +411,6 @@ end:
|
|||
if (depth) *depth = 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_font_slave_int_shm_prev_calculate(unsigned int size, unsigned int nglyphs)
|
||||
{
|
||||
unsigned int average;
|
||||
unsigned int newsize;
|
||||
|
||||
if (!nglyphs) return cserve2_shm_size_normalize(1);
|
||||
average = size / nglyphs;
|
||||
|
||||
newsize = MIN_GLYPHS * average;
|
||||
newsize = cserve2_shm_size_normalize(newsize);
|
||||
|
||||
if (newsize > MAX_CACHE_SIZE)
|
||||
return MAX_CACHE_SIZE;
|
||||
|
||||
return newsize;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
_font_slave_int_shm_calculate(Font_Info *fi, unsigned int hint)
|
||||
{
|
||||
|
@ -434,7 +429,7 @@ _font_slave_int_shm_calculate(Font_Info *fi, unsigned int hint)
|
|||
average = size / i; // average glyph size
|
||||
size = MIN_GLYPHS * average;
|
||||
|
||||
size = cserve2_shm_size_normalize(size);
|
||||
size = cserve2_shm_size_normalize(size, 0);
|
||||
|
||||
if (size > MAX_CACHE_SIZE)
|
||||
return MAX_CACHE_SIZE; // Assumes no glyph will be bigger than this
|
||||
|
@ -465,15 +460,12 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED)
|
|||
Slave_Msg_Font_Glyphs_Loaded *response;
|
||||
Font_Info *fi;
|
||||
unsigned int i;
|
||||
unsigned int total_glyphs = 0;
|
||||
#ifdef DEBUG_LOAD_TIME
|
||||
unsigned int gl_load_time = 0;
|
||||
unsigned int gl_render_time = 0;
|
||||
struct timeval tv_start, tv_end;
|
||||
struct timeval rstart, rfinish;
|
||||
#endif
|
||||
Eina_List *caches = NULL;
|
||||
Slave_Msg_Font_Cache *c = NULL;
|
||||
|
||||
fi = msg->font.ftdata2;
|
||||
|
||||
|
@ -483,41 +475,24 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED)
|
|||
|
||||
_font_slave_size_use(fi);
|
||||
|
||||
if (msg->cache.shm)
|
||||
response = malloc(sizeof(*response)
|
||||
+ sizeof(Slave_Msg_Glyph) * (msg->glyphs.nglyphs));
|
||||
if (!response) return NULL;
|
||||
|
||||
response->nglyphs = 0;
|
||||
response->glyphs = (void *) (response + 1);
|
||||
response->mempool = msg->cache.mempool;
|
||||
if (!response->mempool)
|
||||
{
|
||||
c = malloc(sizeof(*c) + sizeof(Slave_Msg_Glyph) *
|
||||
(msg->glyphs.nglyphs));
|
||||
c->nglyphs = 0;
|
||||
c->glyphs = (void *)(c + 1);
|
||||
c->shm = msg->cache.shm;
|
||||
c->usage = msg->cache.usage;
|
||||
caches = eina_list_append(caches, c);
|
||||
total_glyphs = msg->cache.nglyphs;
|
||||
unsigned shmsize = _font_slave_int_shm_calculate(fi, msg->font.hint);
|
||||
response->mempool = cserve2_shared_mempool_new(GLYPH_DATA_ARRAY_TAG,
|
||||
sizeof(Glyph_Data), 0,
|
||||
shmsize);
|
||||
if (!response->mempool) return NULL;
|
||||
}
|
||||
|
||||
if (!fi->shmsize)
|
||||
fi->shmsize = _font_slave_int_shm_calculate(fi, msg->font.hint);
|
||||
|
||||
i = 0;
|
||||
|
||||
while (i < msg->glyphs.nglyphs)
|
||||
for (i = 0; i < msg->glyphs.nglyphs; i++)
|
||||
{
|
||||
Eina_Bool r = EINA_TRUE;
|
||||
|
||||
if (!c)
|
||||
{
|
||||
Shm_Handle *shm;
|
||||
shm = _font_slave_memory_alloc(fi);
|
||||
c = malloc(sizeof(*c) + sizeof(Slave_Msg_Glyph) *
|
||||
(msg->glyphs.nglyphs - i));
|
||||
c->nglyphs = 0;
|
||||
c->glyphs = (void *)(c + 1);
|
||||
c->shm = shm;
|
||||
c->usage = 0;
|
||||
caches = eina_list_append(caches, c);
|
||||
total_glyphs = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOAD_TIME
|
||||
gettimeofday(&tv_start, NULL);
|
||||
#endif
|
||||
|
@ -530,32 +505,14 @@ _font_slave_glyphs_load(const void *cmddata, void *data EINA_UNUSED)
|
|||
tv_start.tv_sec = tv_end.tv_sec;
|
||||
tv_start.tv_usec = tv_end.tv_usec;
|
||||
#endif
|
||||
r = _font_slave_glyph_render(fi, c, msg->glyphs.glyphs[i]);
|
||||
_font_slave_glyph_render(fi, response, msg->glyphs.glyphs[i]);
|
||||
#ifdef DEBUG_LOAD_TIME
|
||||
gettimeofday(&tv_end, NULL);
|
||||
gl_render_time += _timeval_sub(&tv_end, &tv_start);
|
||||
#endif
|
||||
}
|
||||
if (!r) // SHM is full
|
||||
{
|
||||
fi->shmsize = _font_slave_int_shm_prev_calculate
|
||||
(c->usage, total_glyphs);
|
||||
c = NULL;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
total_glyphs++;
|
||||
}
|
||||
|
||||
response = malloc(sizeof(*response) +
|
||||
sizeof(c) * eina_list_count(caches));
|
||||
response->ncaches = eina_list_count(caches);
|
||||
response->caches = (void *)(response + 1);
|
||||
|
||||
i = 0;
|
||||
EINA_LIST_FREE(caches, c)
|
||||
response->caches[i++] = c;
|
||||
|
||||
#ifdef DEBUG_LOAD_TIME
|
||||
response->gl_load_time = gl_load_time;
|
||||
response->gl_render_time = gl_render_time;
|
||||
|
@ -630,6 +587,8 @@ cserve2_font_source_ft_free(void *fontsource)
|
|||
{
|
||||
Font_Source_Info *fsi = fontsource;
|
||||
|
||||
if (!fsi) return;
|
||||
|
||||
FT_Done_Face(fsi->face);
|
||||
free(fsi->data);
|
||||
free(fsi);
|
||||
|
@ -640,6 +599,8 @@ cserve2_font_ft_free(void *fontinfo)
|
|||
{
|
||||
Font_Info *fi = fontinfo;
|
||||
|
||||
if (!fi) return;
|
||||
|
||||
FT_Done_Size(fi->size);
|
||||
free(fi);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,15 +24,68 @@ cserve2_client_error_send(Client *client, unsigned int rid, int error_code)
|
|||
int size;
|
||||
Msg_Error msg;
|
||||
|
||||
// clear the struct with possible paddings, since it is not aligned.
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.base.rid = rid;
|
||||
msg.base.type = CSERVE2_ERROR;
|
||||
msg.error = error_code;
|
||||
// clear the struct with possible paddings, since it is not aligned.
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.base.rid = rid;
|
||||
msg.base.type = CSERVE2_ERROR;
|
||||
msg.error = error_code;
|
||||
|
||||
size = sizeof(msg);
|
||||
cserve2_client_send(client, &size, sizeof(size));
|
||||
cserve2_client_send(client, &msg, sizeof(msg));
|
||||
size = sizeof(msg);
|
||||
cserve2_client_send(client, &size, sizeof(size));
|
||||
cserve2_client_send(client, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void
|
||||
cserve2_index_list_send(int generation_id,
|
||||
const char *strings_index_path,
|
||||
const char *strings_entries_path,
|
||||
const char *files_index_path,
|
||||
const char *images_index_path,
|
||||
const char *fonts_index_path,
|
||||
Client *client)
|
||||
{
|
||||
Eina_Iterator *iter;
|
||||
Msg_Index_List msg;
|
||||
const int size = sizeof(msg);
|
||||
|
||||
if (!client_list)
|
||||
return;
|
||||
|
||||
INF("New shared index: strings: '%s':'%s' files: '%s' images: '%s', fonts: '%s'",
|
||||
strings_index_path, strings_entries_path,
|
||||
files_index_path, images_index_path, fonts_index_path);
|
||||
|
||||
memset(&msg, 0, size);
|
||||
msg.base.type = CSERVE2_INDEX_LIST;
|
||||
msg.generation_id = generation_id;
|
||||
if (strings_index_path)
|
||||
eina_strlcpy(msg.strings_index_path, strings_index_path, 64);
|
||||
if (strings_entries_path)
|
||||
eina_strlcpy(msg.strings_entries_path, strings_entries_path, 64);
|
||||
if (files_index_path)
|
||||
eina_strlcpy(msg.files_index_path, files_index_path, 64);
|
||||
if (images_index_path)
|
||||
eina_strlcpy(msg.images_index_path, images_index_path, 64);
|
||||
if (fonts_index_path)
|
||||
eina_strlcpy(msg.fonts_index_path, fonts_index_path, 64);
|
||||
|
||||
if (!client)
|
||||
{
|
||||
iter = eina_hash_iterator_data_new(client_list);
|
||||
EINA_ITERATOR_FOREACH(iter, client)
|
||||
{
|
||||
DBG("Sending updated list of indexes to client %d", client->id);
|
||||
cserve2_client_send(client, &size, sizeof(size));
|
||||
cserve2_client_send(client, &msg, sizeof(msg));
|
||||
}
|
||||
eina_iterator_free(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("Sending updated list of indexes to client %d", client->id);
|
||||
cserve2_client_send(client, &size, sizeof(size));
|
||||
cserve2_client_send(client, &msg, sizeof(msg));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -82,16 +135,27 @@ static void
|
|||
_cserve2_client_open(Client *client)
|
||||
{
|
||||
Msg_Open *msg = (Msg_Open *)client->msg.buf;
|
||||
const char *path, *key;
|
||||
const char *path, *key, *end;
|
||||
Evas_Image_Load_Opts *opts = NULL;
|
||||
Evas_Image_Load_Opts opts_copy;
|
||||
|
||||
path = ((const char *)msg) + sizeof(*msg) + msg->path_offset;
|
||||
key = ((const char *)msg) + sizeof(*msg) + msg->key_offset;
|
||||
end = key + strlen(key) + 1;
|
||||
|
||||
INF("Received OPEN command: RID=%d", msg->base.rid);
|
||||
INF("File_ID: %d, path=\"%s\", key=\"%s\", has_load_opts=%d",
|
||||
msg->file_id, path, key, (int) msg->has_load_opts);
|
||||
|
||||
cserve2_cache_file_open(client, msg->file_id, path, key, msg->base.rid);
|
||||
if (!key[0]) key = NULL;
|
||||
if (msg->has_load_opts)
|
||||
{
|
||||
opts = &opts_copy;
|
||||
memcpy(&opts_copy, end, sizeof(opts_copy));
|
||||
}
|
||||
|
||||
cserve2_cache_file_open(client, msg->file_id, path, key, msg->base.rid,
|
||||
opts);
|
||||
|
||||
if (!msg->has_load_opts)
|
||||
cserve2_cache_image_entry_create(client, msg->base.rid,
|
||||
|
@ -99,8 +163,6 @@ _cserve2_client_open(Client *client)
|
|||
else
|
||||
{
|
||||
// FIXME: Check message size first?
|
||||
Evas_Image_Load_Opts *opts =
|
||||
(Evas_Image_Load_Opts*) (key + strlen(key) + 1);
|
||||
|
||||
DBG("Load Options:");
|
||||
DBG("\tdpi: %03.1f", opts->dpi);
|
||||
|
@ -172,8 +234,8 @@ _cserve2_client_font_glyphs_request(Client *client)
|
|||
|
||||
if (msg->base.type == CSERVE2_FONT_GLYPHS_LOAD)
|
||||
{
|
||||
INF("Received CSERVE2_FONT_GLYPHS_LOAD command: RID=%d",
|
||||
msg->base.rid);
|
||||
INF("Received CSERVE2_FONT_GLYPHS_LOAD command: RID=%d (%d glyphs)",
|
||||
msg->base.rid, msg->nglyphs);
|
||||
cserve2_cache_font_glyphs_load(client, source, fontpath,
|
||||
msg->hint, msg->rend_flags, msg->size,
|
||||
msg->dpi, glyphs, msg->nglyphs,
|
||||
|
@ -181,8 +243,8 @@ _cserve2_client_font_glyphs_request(Client *client)
|
|||
}
|
||||
else
|
||||
{
|
||||
INF("Received CSERVE2_FONT_GLYPHS_USED command: RID=%d",
|
||||
msg->base.rid);
|
||||
INF("Received CSERVE2_FONT_GLYPHS_USED command: RID=%d (%d glyphs)",
|
||||
msg->base.rid, msg->nglyphs);
|
||||
cserve2_cache_font_glyphs_used(client, source, fontpath,
|
||||
msg->hint, msg->rend_flags, msg->size,
|
||||
msg->dpi, glyphs, msg->nglyphs,
|
||||
|
@ -291,6 +353,7 @@ static void
|
|||
_clients_finish(void)
|
||||
{
|
||||
eina_hash_free(client_list);
|
||||
client_list = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -327,34 +390,26 @@ main(int argc EINA_UNUSED, const char *argv[])
|
|||
goto error;
|
||||
}
|
||||
|
||||
cserve2_requests_init();
|
||||
|
||||
cserve2_scale_init();
|
||||
|
||||
cserve2_font_init();
|
||||
|
||||
cserve2_cache_init();
|
||||
|
||||
cserve2_shm_init();
|
||||
|
||||
cserve2_shared_index_init();
|
||||
cserve2_requests_init();
|
||||
cserve2_scale_init();
|
||||
cserve2_font_init();
|
||||
cserve2_cache_init();
|
||||
_clients_setup();
|
||||
|
||||
cserve2_main_loop_run();
|
||||
|
||||
_clients_finish();
|
||||
|
||||
cserve2_cache_shutdown();
|
||||
|
||||
cserve2_font_shutdown();
|
||||
|
||||
cserve2_scale_shutdown();
|
||||
|
||||
cserve2_requests_shutdown();
|
||||
|
||||
cserve2_slaves_shutdown();
|
||||
|
||||
cserve2_main_loop_finish();
|
||||
|
||||
cserve2_shared_index_shutdown();
|
||||
cserve2_shm_shutdown();
|
||||
|
||||
eina_prefix_free(_evas_cserve2_pfx);
|
||||
|
|
|
@ -90,8 +90,9 @@ _signal_handle_child(struct signalfd_siginfo *sinfo EINA_UNUSED)
|
|||
}
|
||||
|
||||
static void
|
||||
_signal_handle_exit(struct signalfd_siginfo *sinfo)
|
||||
_signal_handle_exit(struct signalfd_siginfo *sinfo EINA_UNUSED)
|
||||
{
|
||||
#if CSERVE2_LOG_LEVEL >= 4
|
||||
const char *name;
|
||||
|
||||
switch (sinfo->ssi_signo)
|
||||
|
@ -103,6 +104,7 @@ _signal_handle_exit(struct signalfd_siginfo *sinfo)
|
|||
}
|
||||
|
||||
DBG("Received %s. Honoring request.", name);
|
||||
#endif
|
||||
terminate = EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -129,8 +131,6 @@ _signalfd_handler(int fd, Fd_Flags flags EINA_UNUSED, void *data EINA_UNUSED)
|
|||
_signal_handle_child(&sinfo);
|
||||
break;
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
case SIGQUIT:
|
||||
_signal_handle_exit(&sinfo);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
|
@ -159,10 +159,8 @@ _signalfd_setup(void)
|
|||
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGQUIT);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
sigaddset(&mask, SIGUSR2);
|
||||
sigaddset(&mask, SIGUSR1); // ignored
|
||||
sigaddset(&mask, SIGUSR2); // ignored
|
||||
|
||||
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
|
||||
{
|
||||
|
|
|
@ -172,9 +172,6 @@ cserve2_client_send(Client *client, const void *data, size_t size)
|
|||
// so we must close the connection to the client and remove
|
||||
// its references inside our cache.
|
||||
WRN("Error on socket with client %d: %s", client->id, strerror(errno));
|
||||
if (client->msg.reading)
|
||||
_client_msg_free(client);
|
||||
cserve2_client_del(client);
|
||||
return sent;
|
||||
}
|
||||
if (sent < 0)
|
||||
|
|
|
@ -288,6 +288,38 @@ cserve2_request_cancel_all(Slave_Request *req, Error_Type err)
|
|||
free(req);
|
||||
}
|
||||
|
||||
void
|
||||
cserve2_request_dependents_drop(Slave_Request *req, Slave_Request_Type type)
|
||||
{
|
||||
Slave_Request *dep;
|
||||
Eina_List *l, *l_next;
|
||||
|
||||
if (type != CSERVE2_REQ_IMAGE_SPEC_LOAD)
|
||||
{
|
||||
CRIT("Only CSERVE2_REQ_IMAGE_SPEC_LOAD is supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH_SAFE(req->dependents, l, l_next, dep)
|
||||
{
|
||||
if (dep->type == type)
|
||||
{
|
||||
req->dependents = eina_list_remove_list(req->dependents, l);
|
||||
|
||||
if (dep->processing)
|
||||
dep->cancelled = EINA_TRUE;
|
||||
else
|
||||
{
|
||||
cserve2_entry_request_drop(dep->data, type);
|
||||
requests[type].waiting = eina_inlist_remove(
|
||||
requests[type].waiting, EINA_INLIST_GET(dep));
|
||||
dep->funcs->msg_free(dep->msg, dep->data);
|
||||
free(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cserve2_requests_init(void)
|
||||
{
|
||||
|
|
|
@ -32,7 +32,8 @@ _cserve2_rgba_image_set(RGBA_Image *im, void *data, int w, int h, int alpha)
|
|||
}
|
||||
|
||||
void
|
||||
cserve2_rgba_image_scale_do(void *src_data, void *dst_data,
|
||||
cserve2_rgba_image_scale_do(void *src_data, int src_full_w, int src_full_h,
|
||||
void *dst_data,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
int alpha, int smooth)
|
||||
|
@ -40,8 +41,7 @@ cserve2_rgba_image_scale_do(void *src_data, void *dst_data,
|
|||
RGBA_Image src, dst;
|
||||
RGBA_Draw_Context ct;
|
||||
|
||||
_cserve2_rgba_image_set(&src, src_data, src_w, src_h, alpha);
|
||||
|
||||
_cserve2_rgba_image_set(&src, src_data, src_full_w, src_full_h, alpha);
|
||||
_cserve2_rgba_image_set(&dst, dst_data, dst_w, dst_h, alpha);
|
||||
dst.flags = RGBA_IMAGE_NOTHING;
|
||||
|
||||
|
|
|
@ -28,13 +28,14 @@ struct _Shm_Handle
|
|||
size_t map_size;
|
||||
size_t image_size;
|
||||
int refcount;
|
||||
int shmid;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static int id = 0;
|
||||
|
||||
size_t
|
||||
cserve2_shm_size_normalize(size_t size)
|
||||
cserve2_shm_size_normalize(size_t size, size_t align)
|
||||
{
|
||||
long pagesize;
|
||||
size_t normalized;
|
||||
|
@ -46,7 +47,11 @@ cserve2_shm_size_normalize(size_t size)
|
|||
pagesize = 4096;
|
||||
}
|
||||
|
||||
normalized = ((size + pagesize - 1) / pagesize) * pagesize;
|
||||
if (align)
|
||||
align = ((align + pagesize - 1) / pagesize) * pagesize;
|
||||
else
|
||||
align = pagesize;
|
||||
normalized = ((size + align - 1) / align) * align;
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
@ -76,8 +81,8 @@ cserve2_shm_request(const char *infix, size_t size)
|
|||
}
|
||||
|
||||
do {
|
||||
snprintf(shmname, sizeof(shmname), "/evas-shm-%x-%s-%08x",
|
||||
(int) getuid(), infix, id++);
|
||||
snprintf(shmname, sizeof(shmname), "/evas-shm-%05d-%05d-%s-%08x",
|
||||
(int) getuid(), (int) getpid(), infix, ++id);
|
||||
fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||
if (fd == -1 && errno != EEXIST)
|
||||
{
|
||||
|
@ -88,7 +93,7 @@ cserve2_shm_request(const char *infix, size_t size)
|
|||
}
|
||||
} while (fd == -1);
|
||||
|
||||
map_size = cserve2_shm_size_normalize(size);
|
||||
map_size = cserve2_shm_size_normalize(size, 0);
|
||||
|
||||
if (ftruncate(fd, map_size) == -1)
|
||||
{
|
||||
|
@ -110,6 +115,100 @@ cserve2_shm_request(const char *infix, size_t size)
|
|||
|
||||
shm->image_size = size;
|
||||
shm->map_size = map_size;
|
||||
shm->shmid = id;
|
||||
|
||||
return shm;
|
||||
}
|
||||
|
||||
Shm_Handle *
|
||||
cserve2_shm_segment_request(Shm_Handle *shm, size_t size)
|
||||
{
|
||||
Shm_Handle *segment;
|
||||
size_t map_size;
|
||||
Shm_Mapping *map = shm->mapping;
|
||||
int fd;
|
||||
|
||||
segment = calloc(1, sizeof (Shm_Handle));
|
||||
if (!segment) return NULL;
|
||||
|
||||
fd = shm_open(map->name, O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (!fd)
|
||||
{
|
||||
ERR("Could not reopen shm handle: %m");
|
||||
free(segment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map_size = cserve2_shm_size_normalize(size, 0);
|
||||
map_size += map->length;
|
||||
|
||||
if (ftruncate(fd, map_size) == -1)
|
||||
{
|
||||
ERR("Could not set the size of the shm: %m");
|
||||
close(fd);
|
||||
free(segment);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
segment->mapping = map;
|
||||
segment->map_offset = map->length;
|
||||
segment->map_size = map_size - map->length;
|
||||
segment->image_size = size;
|
||||
segment->image_offset = segment->map_offset;
|
||||
map->length = map_size;
|
||||
map->segments = eina_inlist_append(map->segments, EINA_INLIST_GET(segment));
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
Shm_Handle *
|
||||
cserve2_shm_resize(Shm_Handle *shm, size_t newsize)
|
||||
{
|
||||
size_t map_size;
|
||||
int fd;
|
||||
|
||||
if (!shm)
|
||||
return NULL;
|
||||
|
||||
if (shm->map_offset || shm->image_offset)
|
||||
{
|
||||
CRIT("Can not resize shm with non-zero offset");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (eina_inlist_count(shm->mapping->segments) > 1)
|
||||
{
|
||||
CRIT("Can not resize shm with more than one segment");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = shm_open(shm->mapping->name, O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (!fd)
|
||||
{
|
||||
ERR("Could not reopen shm handle: %m");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map_size = cserve2_shm_size_normalize(newsize, 0);
|
||||
if (ftruncate(fd, map_size))
|
||||
{
|
||||
ERR("Could not set the size of the shm: %m");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (shm->data)
|
||||
{
|
||||
munmap(shm->data, shm->image_size);
|
||||
shm->data = mmap(NULL, shm->image_size, PROT_WRITE, MAP_SHARED,
|
||||
fd, shm->image_offset);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
shm->map_size = map_size;
|
||||
shm->image_size = newsize;
|
||||
shm->mapping->length = map_size;
|
||||
|
||||
return shm;
|
||||
}
|
||||
|
@ -139,6 +238,12 @@ cserve2_shm_name_get(const Shm_Handle *shm)
|
|||
return shm->mapping->name;
|
||||
}
|
||||
|
||||
int
|
||||
cserve2_shm_id_get(const Shm_Handle *shm)
|
||||
{
|
||||
return shm->shmid;
|
||||
}
|
||||
|
||||
off_t
|
||||
cserve2_shm_map_offset_get(const Shm_Handle *shm)
|
||||
{
|
||||
|
@ -203,7 +308,7 @@ _cserve2_shm_cleanup()
|
|||
const Eina_File_Direct_Info *f_info;
|
||||
char pattern[NAME_MAX];
|
||||
|
||||
sprintf(pattern, "evas-shm-%x-", (int) getuid());
|
||||
sprintf(pattern, "evas-shm-%05d-", (int) getuid());
|
||||
iter = eina_file_direct_ls("/dev/shm");
|
||||
EINA_ITERATOR_FOREACH(iter, f_info)
|
||||
{
|
||||
|
@ -220,6 +325,7 @@ _cserve2_shm_cleanup()
|
|||
else
|
||||
DBG("cserve2 cleanup: ignoring %s", f_info->path);
|
||||
}
|
||||
eina_iterator_free(iter);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,811 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include "evas_cs2.h"
|
||||
|
||||
#define SHM_FOLDER "/dev/shm"
|
||||
static int _evas_cserve2_shm_debug_log_dom = -1;
|
||||
|
||||
#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__)
|
||||
#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__)
|
||||
#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__)
|
||||
#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__)
|
||||
|
||||
typedef struct _Shm_File Shm_File;
|
||||
struct _Shm_File
|
||||
{
|
||||
Eina_File *f;
|
||||
char *data;
|
||||
size_t size;
|
||||
int tag;
|
||||
|
||||
Eina_Bool strings;
|
||||
Shared_Array_Header *header;
|
||||
};
|
||||
|
||||
Shm_File *sf_strindex = NULL;
|
||||
Shm_File *sf_strpool = NULL;
|
||||
Shm_File *sf_fonts = NULL;
|
||||
Shm_File *sf_files = NULL;
|
||||
Shm_File *sf_images = NULL;
|
||||
|
||||
static int _termsize = 0;
|
||||
|
||||
static void
|
||||
nprintf(int n, const char *fmt, ...)
|
||||
{
|
||||
char buf[n+1];
|
||||
va_list arg;
|
||||
int len;
|
||||
|
||||
va_start(arg, fmt);
|
||||
if (!n)
|
||||
vprintf(fmt, arg);
|
||||
else
|
||||
{
|
||||
len = vsnprintf(buf, n+1, fmt, arg);
|
||||
buf[n] = 0;
|
||||
fputs(buf, stdout);
|
||||
if ((len > 0) && (buf[len-1] != '\n'))
|
||||
fputc('\n', stdout);
|
||||
}
|
||||
va_end(arg);
|
||||
}
|
||||
|
||||
#define printf(...) nprintf(_termsize, __VA_ARGS__)
|
||||
|
||||
static Shm_File *
|
||||
_shm_file_open(const char *path)
|
||||
{
|
||||
Shm_File *sf;
|
||||
Eina_File *f;
|
||||
char *data;
|
||||
|
||||
f = eina_file_open(path, EINA_TRUE);
|
||||
if (!f)
|
||||
{
|
||||
ERR("Could not open file %s: [%d] %m", path, errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = eina_file_map_all(f, EINA_FILE_RANDOM);
|
||||
if (!data)
|
||||
{
|
||||
ERR("Could not map the file %s", path);
|
||||
eina_file_close(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sf = calloc(1, sizeof(*sf));
|
||||
sf->data = data;
|
||||
sf->f = f;
|
||||
sf->size = eina_file_size_get(f);
|
||||
|
||||
DBG("Successfully opened %s", path);
|
||||
return sf;
|
||||
}
|
||||
|
||||
static void
|
||||
_shm_file_close(Shm_File *sf)
|
||||
{
|
||||
if (!sf) return;
|
||||
eina_file_map_free(sf->f, sf->data);
|
||||
eina_file_close(sf->f);
|
||||
free(sf);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_shm_file_probe(Shm_File *sf)
|
||||
{
|
||||
if (!sf || !sf->data)
|
||||
return EINA_FALSE;
|
||||
|
||||
if (sf->size < sizeof(Shared_Array_Header))
|
||||
{
|
||||
sf->header = NULL;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
sf->header = (Shared_Array_Header *) sf->data;
|
||||
switch (sf->header->tag)
|
||||
{
|
||||
case STRING_INDEX_ARRAY_TAG:
|
||||
DBG("Found string index: %s", eina_file_filename_get(sf->f));
|
||||
if (sf->header->elemsize != sizeof(Index_Entry))
|
||||
{
|
||||
ERR("String index looks invalid: elemsize %d",
|
||||
sf->header->elemsize);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
sf->tag = STRING_INDEX_ARRAY_TAG;
|
||||
sf_strindex = sf;
|
||||
break;
|
||||
|
||||
case STRING_MEMPOOL_FAKETAG:
|
||||
DBG("Found string mempool: %s", eina_file_filename_get(sf->f));
|
||||
sf->strings = EINA_TRUE;
|
||||
sf->tag = STRING_MEMPOOL_FAKETAG;
|
||||
sf->header = NULL;
|
||||
sf_strpool = sf;
|
||||
break;
|
||||
|
||||
case FILE_DATA_ARRAY_TAG:
|
||||
DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag);
|
||||
sf->tag = sf->header->tag;
|
||||
sf_files = sf;
|
||||
break;
|
||||
|
||||
case IMAGE_DATA_ARRAY_TAG:
|
||||
DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag);
|
||||
sf->tag = sf->header->tag;
|
||||
sf_images = sf;
|
||||
break;
|
||||
|
||||
case FONT_DATA_ARRAY_TAG:
|
||||
DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag);
|
||||
sf->tag = sf->header->tag;
|
||||
sf_fonts = sf;
|
||||
break;
|
||||
|
||||
case GLYPH_DATA_ARRAY_TAG:
|
||||
DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag);
|
||||
sf->tag = sf->header->tag;
|
||||
break;
|
||||
|
||||
default:
|
||||
//DBG("Unknown tag found: %d", sf->header->tag);
|
||||
sf->header = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_List *
|
||||
_shm_files_list(const char *folder)
|
||||
{
|
||||
Eina_List *lst = NULL;
|
||||
Eina_Iterator *iter;
|
||||
const Eina_File_Direct_Info *f_info;
|
||||
char pattern[64];
|
||||
|
||||
sprintf(pattern, "/evas-shm-%05d-", (int) getuid());
|
||||
iter = eina_file_direct_ls(folder);
|
||||
EINA_ITERATOR_FOREACH(iter, f_info)
|
||||
{
|
||||
if (strstr(f_info->path, pattern))
|
||||
{
|
||||
const char *shmname = strrchr(f_info->path, '/');
|
||||
if (!shmname) continue;
|
||||
|
||||
lst = eina_list_append(lst, strdup(shmname));
|
||||
}
|
||||
else
|
||||
DBG("cserve2 scan: ignoring %s", f_info->path);
|
||||
}
|
||||
eina_iterator_free(iter);
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
||||
static void
|
||||
printf_newline(Eina_Bool flush)
|
||||
{
|
||||
printf("----------------------------------------------------------------"
|
||||
"----------------\n");
|
||||
|
||||
if (flush)
|
||||
{
|
||||
printf("\n\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_index_tables_summary_print(void)
|
||||
{
|
||||
printf("Shared index tables\n\n");
|
||||
printf("Table Tag MapSize Gen ElSz Count Last Sort Path\n");
|
||||
printf_newline(0);
|
||||
|
||||
printf("StrIdx %4.4s %7d %4d %4d %5d %5d %5d %s\n",
|
||||
(char *) &sf_strindex->tag,
|
||||
(int) eina_file_size_get(sf_strindex->f),
|
||||
sf_strindex->header->generation_id, sf_strindex->header->elemsize,
|
||||
sf_strindex->header->count, sf_strindex->header->emptyidx,
|
||||
sf_strindex->header->sortedidx,
|
||||
eina_file_filename_get(sf_strindex->f));
|
||||
|
||||
printf("StrData %4.4s %7d %s\n",
|
||||
(char *) &sf_strpool->tag,
|
||||
(int) eina_file_size_get(sf_strpool->f),
|
||||
eina_file_filename_get(sf_strpool->f));
|
||||
|
||||
if (sf_files)
|
||||
printf("FileIdx %4.4s %7d %4d %4d %5d %5d %5d %s\n",
|
||||
(char *) &sf_files->tag,
|
||||
(int) eina_file_size_get(sf_files->f),
|
||||
sf_files->header->generation_id, sf_files->header->elemsize,
|
||||
sf_files->header->count, sf_files->header->emptyidx,
|
||||
sf_files->header->sortedidx,
|
||||
eina_file_filename_get(sf_files->f));
|
||||
else
|
||||
printf("FileIdx <not found>\n");
|
||||
|
||||
if (sf_images)
|
||||
printf("Images %4.4s %7d %4d %4d %5d %5d %5d %s\n",
|
||||
(char *) &sf_images->tag,
|
||||
(int) eina_file_size_get(sf_images->f),
|
||||
sf_images->header->generation_id, sf_images->header->elemsize,
|
||||
sf_images->header->count, sf_images->header->emptyidx,
|
||||
sf_images->header->sortedidx,
|
||||
eina_file_filename_get(sf_images->f));
|
||||
else
|
||||
printf("Images <not found>\n");
|
||||
|
||||
if (sf_fonts)
|
||||
printf("FontIdx %4.4s %7d %4d %4d %5d %5d %5d %s\n",
|
||||
(char *) &sf_fonts->tag,
|
||||
(int) eina_file_size_get(sf_fonts->f),
|
||||
sf_fonts->header->generation_id, sf_fonts->header->elemsize,
|
||||
sf_fonts->header->count, sf_fonts->header->emptyidx,
|
||||
sf_fonts->header->sortedidx,
|
||||
eina_file_filename_get(sf_fonts->f));
|
||||
else
|
||||
printf("FontIdx <not found>\n");
|
||||
|
||||
printf_newline(1);
|
||||
}
|
||||
|
||||
static const Shm_Object *
|
||||
_shared_index_item_get_by_id(Shm_File *si, int elemsize, unsigned int id)
|
||||
{
|
||||
const Shm_Object *obj;
|
||||
const char *base;
|
||||
int low = 0, high, start_high;
|
||||
int cur;
|
||||
|
||||
if (!si || elemsize <= 0 || !id)
|
||||
return NULL;
|
||||
|
||||
// FIXME: HACK (consider all arrays always sorted by id)
|
||||
high = si->header->emptyidx; // Should be si->header->sortedidx
|
||||
|
||||
if (high > si->header->count)
|
||||
high = si->header->count;
|
||||
|
||||
base = si->data + sizeof(Shared_Array_Header);
|
||||
|
||||
// Direct access, works for non-repacked arrays
|
||||
if ((int) id < high)
|
||||
{
|
||||
obj = (Shm_Object *) (base + (elemsize * id));
|
||||
if (obj->id == id)
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Binary search
|
||||
start_high = high;
|
||||
while(high != low)
|
||||
{
|
||||
cur = low + ((high - low) / 2);
|
||||
obj = (Shm_Object *) (base + (elemsize * cur));
|
||||
if (obj->id == id)
|
||||
return obj;
|
||||
if (obj->id < id)
|
||||
low = cur + 1;
|
||||
else
|
||||
high = cur;
|
||||
}
|
||||
|
||||
// Linear search
|
||||
for (cur = start_high; cur < si->header->count; cur++)
|
||||
{
|
||||
obj = (Shm_Object *) (base + (elemsize * cur));
|
||||
if (!obj->id)
|
||||
return NULL;
|
||||
if (obj->id == id)
|
||||
return obj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
_shared_array_item_get(Shm_File *sf, int idx)
|
||||
{
|
||||
if (!sf || !sf->header || idx < 0)
|
||||
return NULL;
|
||||
|
||||
if ((idx + 1) * sf->header->elemsize > (int) sf->size)
|
||||
return NULL;
|
||||
|
||||
return (sf->data + sizeof(Shared_Array_Header) + idx * sf->header->elemsize);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_shared_string_get(int id)
|
||||
{
|
||||
Index_Entry *ie;
|
||||
|
||||
ie = (Index_Entry *)
|
||||
_shared_index_item_get_by_id(sf_strindex, sizeof(*ie), id);
|
||||
if (!ie) return NULL;
|
||||
if (ie->offset < 0) return NULL;
|
||||
if (!ie->refcount) return NULL;
|
||||
if (ie->offset + ie->length > (int) sf_strpool->size) return NULL;
|
||||
|
||||
return sf_strpool->data + ie->offset;
|
||||
}
|
||||
|
||||
static void
|
||||
_strings_all_print(Eina_Bool full)
|
||||
{
|
||||
int k;
|
||||
const char *mindata = sf_strpool->data;
|
||||
const char *maxdata = sf_strpool->data + sf_strpool->size;
|
||||
|
||||
printf("List of strings\n");
|
||||
printf("Indexes: %s\n", eina_file_filename_get(sf_strindex->f));
|
||||
printf("Data: %s\n", eina_file_filename_get(sf_strpool->f));
|
||||
printf(" String BufID Refcnt Offset Buflen Content\n");
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_strindex->header->count; k++)
|
||||
{
|
||||
Index_Entry *ie;
|
||||
const char *data;
|
||||
|
||||
ie = _shared_array_item_get(sf_strindex, k);
|
||||
if (!ie) break;
|
||||
|
||||
if (!ie->id || (!full && !ie->refcount))
|
||||
continue;
|
||||
|
||||
data = sf_strpool->data + ie->offset;
|
||||
if ((data < mindata) || (data + ie->length > maxdata))
|
||||
data = "<invalid offset>";
|
||||
|
||||
printf("%7d %7d %7d %7d %7d '%s'\n",
|
||||
k, ie->id, ie->refcount, ie->offset, ie->length, data);
|
||||
}
|
||||
|
||||
printf_newline(1);
|
||||
}
|
||||
|
||||
static void
|
||||
_files_all_print_short()
|
||||
{
|
||||
int k;
|
||||
|
||||
if (!sf_files) return;
|
||||
|
||||
printf("List of image files: %s\n", eina_file_filename_get(sf_files->f));
|
||||
printf("A: Alpha, I: Invalid.\n\n");
|
||||
printf(" Index FileID WIDTHxHEIGHT A I Loader PathID KeyID Path:Key\n");
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_files->header->count; k++)
|
||||
{
|
||||
File_Data *fd;
|
||||
|
||||
fd = _shared_array_item_get(sf_files, k);
|
||||
if (!fd) break;
|
||||
if (!fd->id || !fd->refcount) continue;
|
||||
|
||||
printf("%7d %7d %5dx%-6d %d %d %6.6s %6d %6d '%s':'%s'\n",
|
||||
k, fd->id, fd->w, fd->h, !!fd->alpha, !!fd->invalid,
|
||||
fd->loader_data ? _shared_string_get(fd->loader_data) : "",
|
||||
fd->path, fd->key, _shared_string_get(fd->path),
|
||||
_shared_string_get(fd->key));
|
||||
}
|
||||
|
||||
printf_newline(1);
|
||||
}
|
||||
|
||||
static void
|
||||
_files_all_print_all(void)
|
||||
{
|
||||
int k;
|
||||
|
||||
if (!sf_files) return;
|
||||
|
||||
printf("List of opened image files: %s\n", eina_file_filename_get(sf_files->f));
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_files->header->count; k++)
|
||||
{
|
||||
File_Data *fd;
|
||||
|
||||
fd = _shared_array_item_get(sf_files, k);
|
||||
if (!fd) break;
|
||||
if (!fd->id) continue;
|
||||
|
||||
printf("File #%-8d %d\n", k, fd->id);
|
||||
printf("Path:Key: '%s':'%s'\n",
|
||||
_shared_string_get(fd->path), _shared_string_get(fd->key));
|
||||
printf("LoadOpts: Region: %d,%d-%dx%d\n",
|
||||
fd->lo.region.x, fd->lo.region.y, fd->lo.region.w, fd->lo.region.h);
|
||||
if (fd->lo.dpi != 0)
|
||||
printf(" DPI: %f\n");
|
||||
else
|
||||
printf(" DPI: 0\n");
|
||||
printf(" Requested: %dx%d\n", fd->lo.w, fd->lo.h);
|
||||
printf(" Scale down: %d\n", fd->lo.scale_down_by);
|
||||
printf(" Orientation: %s\n", fd->lo.orientation ? "YES" : "NO");
|
||||
printf("Loader: %s\n", _shared_string_get(fd->loader_data));
|
||||
printf("Geometry: %dx%d\n", fd->w, fd->h);
|
||||
printf("Animation: anim: %s, frames: %d, loop: %d, hint: %d\n",
|
||||
fd->animated ? "YES" : "NO",
|
||||
fd->frame_count, fd->loop_count, fd->loop_hint);
|
||||
printf("Alpha: %s\n", fd->alpha ? "YES" : "NO");
|
||||
printf("Invalid: %s\n", fd->invalid ? "YES" : "NO");
|
||||
|
||||
printf_newline(0);
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
_images_all_print_short(void)
|
||||
{
|
||||
int k;
|
||||
|
||||
if (!sf_images) return;
|
||||
|
||||
printf("List of loaded images: %s\n", eina_file_filename_get(sf_images->f));
|
||||
printf("A: Sparse alpha, U: Unused, L: Load requested.\n\n");
|
||||
printf(" Index ImageID FileID Refcnt A U L ShmID ShmPath\n");
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_images->header->count; k++)
|
||||
{
|
||||
Image_Data *id;
|
||||
|
||||
id = _shared_array_item_get(sf_images, k);
|
||||
if (!id) break;
|
||||
if (!id->id || !id->refcount) continue;
|
||||
|
||||
printf("%7d %7d %7d %7d %d %d %d %7d '%s'\n",
|
||||
k, id->id, id->file_id, id->refcount,
|
||||
!!id->alpha_sparse, !!id->unused, !!id->doload, id->shm_id,
|
||||
id->shm_id ? _shared_string_get(id->shm_id) : "");
|
||||
}
|
||||
|
||||
printf_newline(1);
|
||||
}
|
||||
|
||||
static void
|
||||
_images_all_print_full(void)
|
||||
{
|
||||
int k;
|
||||
|
||||
if (!sf_images) return;
|
||||
|
||||
printf("List of loaded images: %s\n\n",
|
||||
eina_file_filename_get(sf_images->f));
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_images->header->count; k++)
|
||||
{
|
||||
Image_Data *id;
|
||||
File_Data *fd;
|
||||
const char *scale_hint;
|
||||
|
||||
id = _shared_array_item_get(sf_images, k);
|
||||
if (!id) break;
|
||||
if (!id->id) continue;
|
||||
|
||||
printf("Image #%-8d %d\n", k, id->id);
|
||||
printf("Refcount %d\n", id->refcount);
|
||||
printf("Sparse alpha %s\n"
|
||||
"Unused: %s\n"
|
||||
"Load requested: %s\n"
|
||||
"Valid: %s\n",
|
||||
id->alpha_sparse ? "YES" : "NO",
|
||||
id->unused ? "YES" : "NO",
|
||||
id->doload ? "YES" : "NO",
|
||||
id->valid ? "YES" : "NO");
|
||||
printf("Shm Path: '%s'\n",
|
||||
id->shm_id ? _shared_string_get(id->shm_id) : "");
|
||||
printf("LoadOpts: width %d\n", id->opts.w);
|
||||
printf(" height %d\n", id->opts.h);
|
||||
printf(" degree %d\n", id->opts.degree);
|
||||
printf(" scale_down_by %d\n", id->opts.scale_down_by);
|
||||
if (id->opts.dpi)
|
||||
printf(" dpi %.2f\n", id->opts.dpi);
|
||||
else
|
||||
printf(" dpi 0\n");
|
||||
printf(" orientation %s\n", id->opts.orientation ? "YES" : "NO");
|
||||
printf(" region (%d,%d) %dx%d\n",
|
||||
id->opts.region.x, id->opts.region.y,
|
||||
id->opts.region.w, id->opts.region.h);
|
||||
|
||||
switch (id->opts.scale_load.scale_hint)
|
||||
{
|
||||
case EVAS_IMAGE_SCALE_HINT_NONE:
|
||||
scale_hint = "EVAS_IMAGE_SCALE_HINT_NONE"; break;
|
||||
case EVAS_IMAGE_SCALE_HINT_DYNAMIC:
|
||||
scale_hint = "EVAS_IMAGE_SCALE_HINT_DYNAMIC"; break;
|
||||
case EVAS_IMAGE_SCALE_HINT_STATIC:
|
||||
scale_hint = "EVAS_IMAGE_SCALE_HINT_STATIC"; break;
|
||||
default:
|
||||
scale_hint = "<invalid>"; break;
|
||||
}
|
||||
|
||||
printf(" scale src (%d,%d) %dx%d\n",
|
||||
id->opts.scale_load.src_x, id->opts.scale_load.src_y,
|
||||
id->opts.scale_load.src_w, id->opts.scale_load.src_h);
|
||||
printf(" scale dst %dx%d\n",
|
||||
id->opts.scale_load.dst_w, id->opts.scale_load.dst_h);
|
||||
printf(" scale smooth %s\n",
|
||||
id->opts.scale_load.smooth ? "YES" : "NO");
|
||||
printf(" scale hint %s (%d)\n",
|
||||
scale_hint, id->opts.scale_load.scale_hint);
|
||||
|
||||
fd = (File_Data *)
|
||||
_shared_index_item_get_by_id(sf_files, sizeof(*fd), id->file_id);
|
||||
if (fd)
|
||||
{
|
||||
printf("File: ID %d\n", id->file_id);
|
||||
printf(" Path:Key: '%s':'%s'\n",
|
||||
_shared_string_get(fd->path), _shared_string_get(fd->key));
|
||||
printf(" Loader: %s\n",
|
||||
_shared_string_get(fd->loader_data));
|
||||
printf(" Geometry: %dx%d\n", fd->w, fd->h);
|
||||
printf(" Animation: anim: %s, frames: %d, loop: %d, hint: %d\n",
|
||||
fd->animated ? "YES" : "NO",
|
||||
fd->frame_count, fd->loop_count, fd->loop_hint);
|
||||
printf(" Alpha: %s\n", fd->alpha ? "YES" : "NO");
|
||||
printf(" Invalid: %s\n", fd->invalid ? "YES" : "NO");
|
||||
}
|
||||
else
|
||||
printf("File: ID %d not found\n", id->file_id);
|
||||
|
||||
printf_newline(0);
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
_fonts_all_print_short(void)
|
||||
{
|
||||
int k;
|
||||
|
||||
static const char *rend_flags[] = { "R", "S", "W", "SW", "X" };
|
||||
|
||||
if (!sf_fonts) return;
|
||||
|
||||
printf("List of loaded fonts: %s\n", eina_file_filename_get(sf_fonts->f));
|
||||
printf("Rendering flags (RF): "
|
||||
"R: Regular, S: Slanted, W: Weight, X: Invalid\n\n");
|
||||
printf(" Index FontID Refcnt Size DPI RF GlIdx GlData File[:Name]\n");
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_fonts->header->count; k++)
|
||||
{
|
||||
Font_Data *fd;
|
||||
int rflag;
|
||||
const char *rf;
|
||||
|
||||
fd = _shared_array_item_get(sf_fonts, k);
|
||||
if (!fd) break;
|
||||
if (!fd->id || !fd->refcount) continue;
|
||||
|
||||
rflag = fd->rend_flags;
|
||||
if (rflag < 0 || rflag > 3) rflag = 4;
|
||||
rf = rend_flags[rflag];
|
||||
|
||||
if (fd->name)
|
||||
printf("%6d %6d %6d %5d %5d %-2s %6d %6d '%s':'%s'\n",
|
||||
k, fd->id, fd->refcount, fd->size, fd->dpi, rf,
|
||||
fd->glyph_index_shm, fd->mempool_shm,
|
||||
fd->file ? _shared_string_get(fd->file) : "",
|
||||
_shared_string_get(fd->name));
|
||||
else
|
||||
printf("%6d %6d %6d %5d %5d %-2s %6d %6d '%s'\n",
|
||||
k, fd->id, fd->refcount, fd->size, fd->dpi, rf,
|
||||
fd->glyph_index_shm, fd->mempool_shm,
|
||||
fd->file ? _shared_string_get(fd->file) : "");
|
||||
}
|
||||
|
||||
printf_newline(1);
|
||||
}
|
||||
|
||||
static void
|
||||
_glyphs_all_print(Shm_File *sf)
|
||||
{
|
||||
int k;
|
||||
int nglyphs = 0;
|
||||
int mem_used = 0;
|
||||
|
||||
printf(" GlyphID Refcnt Index Size Rows Width Pitch Grays H M "
|
||||
"BufID Offset ShmPath\n");
|
||||
|
||||
for (k = 0; k < sf->header->count; k++)
|
||||
{
|
||||
Glyph_Data *gd;
|
||||
|
||||
gd = _shared_array_item_get(sf, k);
|
||||
if (!gd) break;
|
||||
if (!gd->id) continue;
|
||||
|
||||
printf(" %8u %6u %6u %5u %5u %5u %5u %5u %1u %1u %6u %6u '%s'\n",
|
||||
gd->id, gd->refcount, gd->index, gd->size, gd->rows, gd->width,
|
||||
gd->pitch, gd->num_grays, gd->hint, gd->pixel_mode, gd->buffer_id,
|
||||
gd->offset, _shared_string_get(gd->mempool_id));
|
||||
|
||||
nglyphs++;
|
||||
mem_used += gd->size;
|
||||
}
|
||||
|
||||
printf("Total %d glyph(s) loaded, using %d bytes (w/o padding)\n",
|
||||
nglyphs, mem_used);
|
||||
}
|
||||
|
||||
static void
|
||||
_fonts_all_print_full(void)
|
||||
{
|
||||
int k;
|
||||
|
||||
static const char *rend_flags[] = { "R", "S", "W", "SW", "X" };
|
||||
|
||||
if (!sf_fonts) return;
|
||||
|
||||
printf("List of loaded fonts: %s\n", eina_file_filename_get(sf_fonts->f));
|
||||
printf("Rendering flags: "
|
||||
"R: Regular, S: Slanted, W: Weight, X: Invalid\n");
|
||||
printf("H: Hint, M: Pixel mode\n\n");
|
||||
printf_newline(0);
|
||||
|
||||
for (k = 0; k < sf_fonts->header->count; k++)
|
||||
{
|
||||
Shm_File *sf;
|
||||
Font_Data *fd;
|
||||
int rflag;
|
||||
const char *rf;
|
||||
|
||||
fd = _shared_array_item_get(sf_fonts, k);
|
||||
if (!fd) break;
|
||||
if (!fd->id) continue;
|
||||
if (!fd->glyph_index_shm) continue;
|
||||
|
||||
sf = _shm_file_open(_shared_string_get(fd->glyph_index_shm));
|
||||
if (!_shm_file_probe(sf))
|
||||
{
|
||||
_shm_file_close(sf);
|
||||
continue;
|
||||
}
|
||||
|
||||
rflag = fd->rend_flags;
|
||||
if (rflag < 0 || rflag > 3) rflag = 4;
|
||||
rf = rend_flags[rflag];
|
||||
|
||||
printf("Font #%-8d %d\n", k, fd->id);
|
||||
printf("Refcount %d\n", fd->refcount);
|
||||
printf("File '%s'\n", _shared_string_get(fd->file));
|
||||
printf("Name '%s'\n",
|
||||
fd->name ? _shared_string_get(fd->name) : "");
|
||||
printf("Size %d\n", fd->size);
|
||||
printf("DPI %d\n", fd->dpi);
|
||||
printf("Rendering flag %s (%d)\n", rf, fd->rend_flags);
|
||||
printf("Glyph index '%s'\n", _shared_string_get(fd->glyph_index_shm));
|
||||
printf("Glyph data '%s'\n", _shared_string_get(fd->mempool_shm));
|
||||
|
||||
_glyphs_all_print(sf);
|
||||
|
||||
_shm_file_close(sf);
|
||||
printf_newline(0);
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
|
||||
{
|
||||
Eina_List *opened_sf = NULL;
|
||||
Eina_List *shmfiles = NULL, *l1, *l2;
|
||||
const char *shmfolder = SHM_FOLDER;
|
||||
Eina_Bool full = EINA_FALSE;
|
||||
Shm_File *sf;
|
||||
char *name;
|
||||
struct winsize w;
|
||||
|
||||
if (isatty(STDOUT_FILENO))
|
||||
{
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
_termsize = w.ws_col;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
if (!strcmp(argv[1], "-h"))
|
||||
{
|
||||
printf("Usage: %s [-f] [folder]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
else if (!strcmp(argv[1], "-f"))
|
||||
{
|
||||
full = EINA_TRUE;
|
||||
if (argc > 2)
|
||||
shmfolder = argv[2];
|
||||
}
|
||||
else
|
||||
shmfolder = argv[1];
|
||||
}
|
||||
|
||||
eina_init();
|
||||
_evas_cserve2_shm_debug_log_dom = eina_log_domain_register
|
||||
("evas_cserve2_shm_debug", EINA_COLOR_BLUE);
|
||||
|
||||
shmfiles = _shm_files_list(shmfolder);
|
||||
if (!shmfiles)
|
||||
{
|
||||
WRN("No shm file was found in %s", shmfolder);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DBG("Found %d files in %s", eina_list_count(shmfiles), shmfolder);
|
||||
|
||||
// Look for strings index & mempool
|
||||
EINA_LIST_FOREACH_SAFE(shmfiles, l1, l2, name)
|
||||
{
|
||||
sf = _shm_file_open(name);
|
||||
if (!_shm_file_probe(sf))
|
||||
{
|
||||
shmfiles = eina_list_remove_list(shmfiles, l1);
|
||||
_shm_file_close(sf);
|
||||
free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sf->tag)
|
||||
_shm_file_close(sf);
|
||||
else
|
||||
opened_sf = eina_list_append(opened_sf, sf);
|
||||
|
||||
if (!!sf_strindex
|
||||
&& !!sf_strpool
|
||||
&& !!sf_fonts
|
||||
&& !!sf_images
|
||||
&& !!sf_files)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sf_strindex || !sf_strpool)
|
||||
{
|
||||
ERR("Could not identify strings memory pool");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
_index_tables_summary_print();
|
||||
_strings_all_print(full);
|
||||
_files_all_print_short();
|
||||
if (full) _files_all_print_all();
|
||||
_images_all_print_short();
|
||||
if (full) _images_all_print_full();
|
||||
_fonts_all_print_short();
|
||||
if (full) _fonts_all_print_full();
|
||||
|
||||
finish:
|
||||
EINA_LIST_FREE(opened_sf, sf)
|
||||
_shm_file_close(sf);
|
||||
|
||||
EINA_LIST_FREE(shmfiles, name)
|
||||
free(name);
|
||||
|
||||
eina_shutdown();
|
||||
return 0;
|
||||
}
|
|
@ -318,7 +318,8 @@ _image_file_header(Eina_File *fd, Eina_Stringshare *key, Evas_Image_Load_Opts *l
|
|||
|
||||
static Error_Type
|
||||
image_open(const char *file, const char *key,
|
||||
Slave_Msg_Image_Opened *result, const char **use_loader)
|
||||
Slave_Msg_Image_Opened *result, const char **use_loader,
|
||||
Evas_Image_Load_Opts *load_opts)
|
||||
{
|
||||
Evas_Module *module;
|
||||
Eina_File *fd;
|
||||
|
@ -327,9 +328,6 @@ image_open(const char *file, const char *key,
|
|||
unsigned int i;
|
||||
Error_Type ret = CSERVE2_NONE;
|
||||
Eina_Stringshare *skey = eina_stringshare_add(key);
|
||||
Evas_Image_Load_Opts load_opts;
|
||||
|
||||
memset(&load_opts, 0, sizeof(load_opts));
|
||||
|
||||
fd = eina_file_open(file, EINA_FALSE);
|
||||
if (!fd)
|
||||
|
@ -344,7 +342,7 @@ image_open(const char *file, const char *key,
|
|||
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||
if (module)
|
||||
{
|
||||
if (_image_file_header(fd, skey, &load_opts, result, module))
|
||||
if (_image_file_header(fd, skey, load_opts, result, module))
|
||||
goto success;
|
||||
}
|
||||
|
||||
|
@ -364,7 +362,7 @@ try_extension:
|
|||
if (loader)
|
||||
{
|
||||
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||
if (_image_file_header(fd, skey, &load_opts, result, module))
|
||||
if (module && _image_file_header(fd, skey, load_opts, result, module))
|
||||
goto success;
|
||||
loader = NULL;
|
||||
module = NULL;
|
||||
|
@ -376,7 +374,7 @@ try_extension:
|
|||
loader = loaders_name[i];
|
||||
module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
|
||||
if (!module) continue;
|
||||
if (_image_file_header(fd, skey, &load_opts, result, module))
|
||||
if (_image_file_header(fd, skey, load_opts, result, module))
|
||||
goto success;
|
||||
}
|
||||
|
||||
|
@ -436,8 +434,8 @@ image_load(const char *file, const char *key, const char *shmfile,
|
|||
}
|
||||
|
||||
memset(&property, 0, sizeof (property));
|
||||
property.w = params->w;
|
||||
property.h = params->h;
|
||||
property.w = params->opts.w; // Should we rather use params->w ?
|
||||
property.h = params->opts.h;
|
||||
|
||||
skey = eina_stringshare_add(key);
|
||||
loader_data = _image_file_open(fd, skey, opts, module, &property, &animated, &funcs);
|
||||
|
@ -448,6 +446,14 @@ image_load(const char *file, const char *key, const char *shmfile,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (params->shm.mmap_size < (int) (property.w * property.h * 4))
|
||||
{
|
||||
printf("LOAD failed at %s:%d: shm map is too small (%d) for this image (%ux%u)\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
params->shm.mmap_size, property.w , property.h);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok = funcs->file_data(loader_data, &property, map, &error);
|
||||
if (!ok || (error != EVAS_LOAD_ERROR_NONE))
|
||||
{
|
||||
|
@ -458,8 +464,9 @@ image_load(const char *file, const char *key, const char *shmfile,
|
|||
|
||||
result->w = property.w;
|
||||
result->h = property.h;
|
||||
result->alpha = property.alpha;
|
||||
|
||||
if (property.alpha)
|
||||
if (property.alpha && property.premul)
|
||||
{
|
||||
result->alpha_sparse = evas_cserve2_image_premul_data((unsigned int *) map,
|
||||
result->w * result->h);
|
||||
|
@ -487,22 +494,32 @@ done:
|
|||
static void
|
||||
handle_image_open(int wfd, void *params)
|
||||
{
|
||||
Slave_Msg_Image_Open *p;
|
||||
Slave_Msg_Image_Open *msg = params;
|
||||
Slave_Msg_Image_Opened result;
|
||||
Evas_Image_Load_Opts load_opts;
|
||||
Error_Type err;
|
||||
const char *loader = NULL, *file, *key, *ptr;
|
||||
char *resp;
|
||||
size_t resp_size;
|
||||
|
||||
p = params;
|
||||
file = (const char *)(p + sizeof(Slave_Msg_Image_Open));
|
||||
memset(&load_opts, 0, sizeof(load_opts));
|
||||
load_opts.region.x = msg->lo.region.x;
|
||||
load_opts.region.y = msg->lo.region.y;
|
||||
load_opts.region.w = msg->lo.region.w;
|
||||
load_opts.region.h = msg->lo.region.h;
|
||||
load_opts.dpi = msg->lo.dpi;
|
||||
load_opts.w = msg->lo.w;
|
||||
load_opts.h = msg->lo.h;
|
||||
load_opts.scale_down_by = msg->lo.scale_down_by;
|
||||
load_opts.orientation = msg->lo.orientation;
|
||||
|
||||
file = (const char *) (msg + 1);
|
||||
key = file + strlen(file) + 1;
|
||||
ptr = key + strlen(key) + 1;
|
||||
if (p->has_loader_data)
|
||||
loader = ptr;
|
||||
loader = ptr;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
if ((err = image_open(file, key, &result, &loader))
|
||||
if ((err = image_open(file, key, &result, &loader, &load_opts))
|
||||
!= CSERVE2_NONE)
|
||||
{
|
||||
printf("OPEN failed at %s:%d\n", __FUNCTION__, __LINE__);
|
||||
|
|
|
@ -128,7 +128,8 @@ _slave_proc_dead_cb(int pid, int status EINA_UNUSED)
|
|||
{
|
||||
Slave_Proc *s;
|
||||
|
||||
DBG("Child dead with pid '%d'.", pid);
|
||||
INF("Child dead with pid '%d': signal %d",
|
||||
pid, WIFSIGNALED(status) ? WTERMSIG(status) : 0);
|
||||
s = _slave_proc_find(pid);
|
||||
if (!s)
|
||||
{
|
||||
|
|
|
@ -176,48 +176,81 @@ _usage_msg_send(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_shared_index_print(Msg_Base *data, size_t size)
|
||||
{
|
||||
Msg_Index_List *msg = (Msg_Index_List *) data;
|
||||
|
||||
if (size < sizeof(*msg) || msg->base.type != CSERVE2_INDEX_LIST)
|
||||
{
|
||||
ERR("Invalid message received from server. "
|
||||
"Something went wrong.");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Printing shared indexes status.\n");
|
||||
printf("===============================\n\n");
|
||||
printf("Generation ID: %-4d\n", msg->generation_id);
|
||||
printf("Strings entries path: %s\n", msg->strings_entries_path);
|
||||
printf("Strings index path: %s\n", msg->strings_index_path);
|
||||
printf("Files index path: %s\n", msg->files_index_path);
|
||||
printf("Images index path: %s\n", msg->images_index_path);
|
||||
printf("Fonts index path: %s\n", msg->fonts_index_path);
|
||||
printf("\n\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
_usage_msg_read(void)
|
||||
{
|
||||
Msg_Stats *msg = NULL;
|
||||
Msg_Stats *stats = NULL;
|
||||
int size;
|
||||
|
||||
printf("Requesting server statistics.\n\n");
|
||||
while (!msg)
|
||||
msg = _server_read(&size);
|
||||
|
||||
if (msg->base.type != CSERVE2_STATS)
|
||||
while (!stats)
|
||||
{
|
||||
ERR("Invalid message received from server."
|
||||
"Something went badly wrong.");
|
||||
return;
|
||||
Msg_Base *msg = _server_read(&size);
|
||||
if (!msg) continue;
|
||||
switch (msg->type)
|
||||
{
|
||||
case CSERVE2_INDEX_LIST:
|
||||
_shared_index_print(msg, size);
|
||||
break;
|
||||
case CSERVE2_STATS:
|
||||
stats = (Msg_Stats *) msg;
|
||||
break;
|
||||
default:
|
||||
ERR("Invalid message received from server. "
|
||||
"Something went badly wrong.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Printing server usage.\n");
|
||||
printf("======================\n\n");
|
||||
printf("\nImage Usage Statistics:\n");
|
||||
printf("----------------------\n\n");
|
||||
printf("Image headers usage: %d bytes\n", msg->images.files_size);
|
||||
printf("Image data requested: %d kbytes\n", msg->images.requested_size / 1024);
|
||||
printf("Image data usage: %d kbytes\n", msg->images.images_size / 1024);
|
||||
printf("Image data unused: %d kbytes\n", msg->images.unused_size / 1024);
|
||||
printf("Image headers load time: %dus\n", msg->images.files_load_time);
|
||||
printf("Image headers saved time: %dus\n", msg->images.files_saved_time);
|
||||
printf("Image data load time: %dus\n", msg->images.images_load_time);
|
||||
printf("Image data saved time: %dus\n", msg->images.images_saved_time);
|
||||
printf("Image headers usage: %d bytes\n", stats->images.files_size);
|
||||
printf("Image data requested: %d kbytes\n", stats->images.requested_size / 1024);
|
||||
printf("Image data usage: %d kbytes\n", stats->images.images_size / 1024);
|
||||
printf("Image data unused: %d kbytes\n", stats->images.unused_size / 1024);
|
||||
printf("Image headers load time: %dus\n", stats->images.files_load_time);
|
||||
printf("Image headers saved time: %dus\n", stats->images.files_saved_time);
|
||||
printf("Image data load time: %dus\n", stats->images.images_load_time);
|
||||
printf("Image data saved time: %dus\n", stats->images.images_saved_time);
|
||||
printf("\nFont Usage Statistics:\n");
|
||||
printf("----------------------\n\n");
|
||||
printf("Requested usage: %d bytes\n", msg->fonts.requested_size);
|
||||
printf("Real usage: %d bytes\n", msg->fonts.real_size);
|
||||
printf("Unused size: %d bytes\n", msg->fonts.unused_size);
|
||||
printf("Fonts load time: %dus\n", msg->fonts.fonts_load_time);
|
||||
printf("Fonts used load time: %dus\n", msg->fonts.fonts_used_load_time);
|
||||
printf("Fonts used saved time: %dus\n", msg->fonts.fonts_used_saved_time);
|
||||
printf("Glyphs load time: %dus\n", msg->fonts.glyphs_load_time);
|
||||
printf("Glyphs render time: %dus\n", msg->fonts.glyphs_render_time);
|
||||
printf("Glyphs saved time: %dus\n", msg->fonts.glyphs_saved_time);
|
||||
printf("Glyphs request time: %dus\n", msg->fonts.glyphs_request_time);
|
||||
printf("Glyphs slave time: %dus\n", msg->fonts.glyphs_slave_time);
|
||||
printf("Requested usage: %d bytes\n", stats->fonts.requested_size);
|
||||
printf("Real usage: %d bytes\n", stats->fonts.real_size);
|
||||
printf("Unused size: %d bytes\n", stats->fonts.unused_size);
|
||||
printf("Fonts load time: %dus\n", stats->fonts.fonts_load_time);
|
||||
printf("Fonts used load time: %dus\n", stats->fonts.fonts_used_load_time);
|
||||
printf("Fonts used saved time: %dus\n", stats->fonts.fonts_used_saved_time);
|
||||
printf("Glyphs load time: %dus\n", stats->fonts.glyphs_load_time);
|
||||
printf("Glyphs render time: %dus\n", stats->fonts.glyphs_render_time);
|
||||
printf("Glyphs saved time: %dus\n", stats->fonts.glyphs_saved_time);
|
||||
printf("Glyphs request time: %dus\n", stats->fonts.glyphs_request_time);
|
||||
printf("Glyphs slave time: %dus\n", stats->fonts.glyphs_slave_time);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
|
|
@ -33,23 +33,23 @@
|
|||
// Default LRU size. If 0, all scaled images will be dropped instantly.
|
||||
#define DEFAULT_CACHE_LRU_SIZE (4*1024*1024)
|
||||
|
||||
static void _evas_cache_image_dirty_add(Image_Entry *im);
|
||||
static void _evas_cache_image_dirty_del(Image_Entry *im);
|
||||
static void _evas_cache_image_activ_add(Image_Entry *im);
|
||||
static void _evas_cache_image_activ_del(Image_Entry *im);
|
||||
static void _evas_cache_image_lru_add(Image_Entry *im);
|
||||
static void _evas_cache_image_lru_del(Image_Entry *im);
|
||||
static void _evas_cache2_image_dirty_add(Image_Entry *im);
|
||||
static void _evas_cache2_image_dirty_del(Image_Entry *im);
|
||||
static void _evas_cache2_image_activ_add(Image_Entry *im);
|
||||
static void _evas_cache2_image_activ_del(Image_Entry *im);
|
||||
static void _evas_cache2_image_lru_add(Image_Entry *im);
|
||||
static void _evas_cache2_image_lru_del(Image_Entry *im);
|
||||
static void _evas_cache2_image_entry_preload_remove(Image_Entry *ie, const void *target);
|
||||
// static void _evas_cache_image_lru_nodata_add(Image_Entry *im);
|
||||
// static void _evas_cache_image_lru_nodata_del(Image_Entry *im);
|
||||
// static void _evas_cache2_image_lru_nodata_add(Image_Entry *im);
|
||||
// static void _evas_cache2_image_lru_nodata_del(Image_Entry *im);
|
||||
|
||||
static void
|
||||
_evas_cache_image_dirty_add(Image_Entry *im)
|
||||
_evas_cache2_image_dirty_add(Image_Entry *im)
|
||||
{
|
||||
if (im->flags.dirty) return;
|
||||
_evas_cache_image_activ_del(im);
|
||||
_evas_cache_image_lru_del(im);
|
||||
// _evas_cache_image_lru_nodata_del(im);
|
||||
_evas_cache2_image_activ_del(im);
|
||||
_evas_cache2_image_lru_del(im);
|
||||
// _evas_cache2_image_lru_nodata_del(im);
|
||||
im->flags.dirty = 1;
|
||||
im->flags.cached = 1;
|
||||
im->cache2->dirty = eina_inlist_prepend(im->cache2->dirty, EINA_INLIST_GET(im));
|
||||
|
@ -61,7 +61,7 @@ _evas_cache_image_dirty_add(Image_Entry *im)
|
|||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_dirty_del(Image_Entry *im)
|
||||
_evas_cache2_image_dirty_del(Image_Entry *im)
|
||||
{
|
||||
if (!im->flags.dirty) return;
|
||||
if (!im->cache2) return;
|
||||
|
@ -71,12 +71,12 @@ _evas_cache_image_dirty_del(Image_Entry *im)
|
|||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_activ_add(Image_Entry *im)
|
||||
_evas_cache2_image_activ_add(Image_Entry *im)
|
||||
{
|
||||
if (im->flags.activ) return;
|
||||
_evas_cache_image_dirty_del(im);
|
||||
_evas_cache_image_lru_del(im);
|
||||
// _evas_cache_image_lru_nodata_del(im);
|
||||
_evas_cache2_image_dirty_del(im);
|
||||
_evas_cache2_image_lru_del(im);
|
||||
// _evas_cache2_image_lru_nodata_del(im);
|
||||
if (!im->cache_key) return;
|
||||
im->flags.activ = 1;
|
||||
im->flags.cached = 1;
|
||||
|
@ -84,7 +84,7 @@ _evas_cache_image_activ_add(Image_Entry *im)
|
|||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_activ_del(Image_Entry *im)
|
||||
_evas_cache2_image_activ_del(Image_Entry *im)
|
||||
{
|
||||
if (!im->flags.activ) return;
|
||||
if (!im->cache_key) return;
|
||||
|
@ -94,12 +94,12 @@ _evas_cache_image_activ_del(Image_Entry *im)
|
|||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_lru_add(Image_Entry *im)
|
||||
_evas_cache2_image_lru_add(Image_Entry *im)
|
||||
{
|
||||
if (im->flags.lru) return;
|
||||
_evas_cache_image_dirty_del(im);
|
||||
_evas_cache_image_activ_del(im);
|
||||
// _evas_cache_image_lru_nodata_del(im);
|
||||
_evas_cache2_image_dirty_del(im);
|
||||
_evas_cache2_image_activ_del(im);
|
||||
// _evas_cache2_image_lru_nodata_del(im);
|
||||
if (!im->cache_key) return;
|
||||
im->flags.lru = 1;
|
||||
im->flags.cached = 1;
|
||||
|
@ -109,7 +109,7 @@ _evas_cache_image_lru_add(Image_Entry *im)
|
|||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_lru_del(Image_Entry *im)
|
||||
_evas_cache2_image_lru_del(Image_Entry *im)
|
||||
{
|
||||
if (!im->flags.lru) return;
|
||||
if (!im->cache_key) return;
|
||||
|
@ -122,19 +122,19 @@ _evas_cache_image_lru_del(Image_Entry *im)
|
|||
|
||||
/*
|
||||
static void
|
||||
_evas_cache_image_lru_nodata_add(Image_Entry *im)
|
||||
_evas_cache2_image_lru_nodata_add(Image_Entry *im)
|
||||
{
|
||||
if (im->flags.lru_nodata) return;
|
||||
_evas_cache_image_dirty_del(im);
|
||||
_evas_cache_image_activ_del(im);
|
||||
_evas_cache_image_lru_del(im);
|
||||
_evas_cache2_image_dirty_del(im);
|
||||
_evas_cache2_image_activ_del(im);
|
||||
_evas_cache2_image_lru_del(im);
|
||||
im->flags.lru = 1;
|
||||
im->flags.cached = 1;
|
||||
im->cache2->lru_nodata = eina_inlist_prepend(im->cache2->lru_nodata, EINA_INLIST_GET(im));
|
||||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_lru_nodata_del(Image_Entry *im)
|
||||
_evas_cache2_image_lru_nodata_del(Image_Entry *im)
|
||||
{
|
||||
if (!im->flags.lru_nodata) return;
|
||||
im->flags.lru = 0;
|
||||
|
@ -177,7 +177,7 @@ _timestamp_build(Image_Timestamp *tstamp, struct stat *st)
|
|||
}
|
||||
|
||||
static void
|
||||
_evas_cache_image_entry_delete(Evas_Cache2 *cache, Image_Entry *ie)
|
||||
_evas_cache2_image_entry_delete(Evas_Cache2 *cache, Image_Entry *ie)
|
||||
{
|
||||
if (!ie) return;
|
||||
|
||||
|
@ -191,10 +191,10 @@ _evas_cache_image_entry_delete(Evas_Cache2 *cache, Image_Entry *ie)
|
|||
return;
|
||||
}
|
||||
|
||||
_evas_cache_image_dirty_del(ie);
|
||||
_evas_cache_image_activ_del(ie);
|
||||
_evas_cache_image_lru_del(ie);
|
||||
// _evas_cache_image_lru_nodata_del(ie);
|
||||
_evas_cache2_image_dirty_del(ie);
|
||||
_evas_cache2_image_activ_del(ie);
|
||||
_evas_cache2_image_lru_del(ie);
|
||||
// _evas_cache2_image_lru_nodata_del(ie);
|
||||
|
||||
|
||||
if (ie->data1)
|
||||
|
@ -220,7 +220,7 @@ _evas_cache_image_entry_delete(Evas_Cache2 *cache, Image_Entry *ie)
|
|||
}
|
||||
|
||||
static Image_Entry *
|
||||
_evas_cache_image_entry_new(Evas_Cache2 *cache,
|
||||
_evas_cache2_image_entry_new(Evas_Cache2 *cache,
|
||||
const char *hkey,
|
||||
Image_Timestamp *tstamp,
|
||||
const char *file,
|
||||
|
@ -264,15 +264,15 @@ _evas_cache_image_entry_new(Evas_Cache2 *cache,
|
|||
{
|
||||
ERR("couldn't load '%s' '%s' with cserve2!",
|
||||
ie->file, ie->key ? ie->key : "");
|
||||
_evas_cache_image_entry_delete(cache, ie);
|
||||
_evas_cache2_image_entry_delete(cache, ie);
|
||||
if (error)
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ie->cache_key) _evas_cache_image_activ_add(ie);
|
||||
else _evas_cache_image_dirty_add(ie);
|
||||
if (ie->cache_key) _evas_cache2_image_activ_add(ie);
|
||||
else _evas_cache2_image_dirty_add(ie);
|
||||
|
||||
if (error)
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
|
@ -319,7 +319,7 @@ _evas_cache2_image_preloaded_cb(void *data, Eina_Bool success)
|
|||
}
|
||||
|
||||
if (ie->flags.delete_me)
|
||||
_evas_cache_image_entry_delete(ie->cache2, ie);
|
||||
_evas_cache2_image_entry_delete(ie->cache2, ie);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -393,7 +393,7 @@ evas_cache2_image_copied_data(Evas_Cache2 *cache, unsigned int w, unsigned int h
|
|||
(cspace == EVAS_COLORSPACE_YCBCR422601_PL))
|
||||
w &= ~0x1;
|
||||
|
||||
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
im = _evas_cache2_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (!im)
|
||||
return NULL;
|
||||
|
||||
|
@ -402,7 +402,7 @@ evas_cache2_image_copied_data(Evas_Cache2 *cache, unsigned int w, unsigned int h
|
|||
evas_cache2_image_surface_alloc(im, w, h);
|
||||
if (cache->func.copied_data(im, w, h, image_data, alpha, cspace) != 0)
|
||||
{
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -423,14 +423,14 @@ evas_cache2_image_data(Evas_Cache2 *cache, unsigned int w, unsigned int h, DATA3
|
|||
(cspace == EVAS_COLORSPACE_YCBCR422601_PL))
|
||||
w &= ~0x1;
|
||||
|
||||
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
im = _evas_cache2_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (!im) return NULL;
|
||||
im->w = w;
|
||||
im->h = h;
|
||||
im->flags.alpha = alpha;
|
||||
if (cache->func.data(im, w, h, image_data, alpha, cspace) != 0)
|
||||
{
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
return NULL;
|
||||
}
|
||||
im->references = 1;
|
||||
|
@ -444,7 +444,7 @@ evas_cache2_image_empty(Evas_Cache2 *cache)
|
|||
{
|
||||
Image_Entry *im;
|
||||
|
||||
im = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
im = _evas_cache2_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (!im)
|
||||
return NULL;
|
||||
|
||||
|
@ -467,7 +467,7 @@ evas_cache2_image_size_set(Image_Entry *im, unsigned int w, unsigned h)
|
|||
if ((im->w == w) && (im->h == h)) return im;
|
||||
|
||||
cache = im->cache2;
|
||||
im2 = _evas_cache_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL,
|
||||
im2 = _evas_cache2_image_entry_new(cache, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
if (!im2) goto on_error;
|
||||
|
||||
|
@ -486,7 +486,7 @@ evas_cache2_image_size_set(Image_Entry *im, unsigned int w, unsigned h)
|
|||
|
||||
on_error:
|
||||
if (im2)
|
||||
_evas_cache_image_entry_delete(cache, im2);
|
||||
_evas_cache2_image_entry_delete(cache, im2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -510,7 +510,7 @@ evas_cache2_init(const Evas_Cache2_Image_Func *cb)
|
|||
}
|
||||
|
||||
static Eina_Bool
|
||||
_evas_cache_image_free_cb(EINA_UNUSED const Eina_Hash *hash, EINA_UNUSED const void *key, void *data, void *fdata)
|
||||
_evas_cache2_image_free_cb(EINA_UNUSED const Eina_Hash *hash, EINA_UNUSED const void *key, void *data, void *fdata)
|
||||
{
|
||||
Eina_List **delete_list = fdata;
|
||||
*delete_list = eina_list_prepend(*delete_list, data);
|
||||
|
@ -526,20 +526,20 @@ evas_cache2_shutdown(Evas_Cache2 *cache)
|
|||
while (cache->lru)
|
||||
{
|
||||
im = (Image_Entry *)cache->lru;
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
}
|
||||
/* This is mad, I am about to destroy image still alive, but we need to prevent leak. */
|
||||
while (cache->dirty)
|
||||
{
|
||||
im = (Image_Entry *)cache->dirty;
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
}
|
||||
|
||||
delete_list = NULL;
|
||||
eina_hash_foreach(cache->activ, _evas_cache_image_free_cb, &delete_list);
|
||||
eina_hash_foreach(cache->activ, _evas_cache2_image_free_cb, &delete_list);
|
||||
while (delete_list)
|
||||
{
|
||||
_evas_cache_image_entry_delete(cache, eina_list_data_get(delete_list));
|
||||
_evas_cache2_image_entry_delete(cache, eina_list_data_get(delete_list));
|
||||
delete_list = eina_list_remove_list(delete_list, delete_list);
|
||||
}
|
||||
|
||||
|
@ -549,8 +549,17 @@ evas_cache2_shutdown(Evas_Cache2 *cache)
|
|||
free(cache);
|
||||
}
|
||||
|
||||
static void
|
||||
_create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key, size_t keylen, Evas_Image_Load_Opts *lo)
|
||||
EAPI Eina_Bool
|
||||
evas_cache2_image_cached(Image_Entry *ie)
|
||||
{
|
||||
if (!ie) return EINA_FALSE;
|
||||
return (ie->cache2 != NULL);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_cache2_image_cache_key_create(char *hkey, const char *path, size_t pathlen,
|
||||
const char *key, size_t keylen,
|
||||
const Evas_Image_Load_Opts *lo)
|
||||
{
|
||||
const char *ckey = "(null)";
|
||||
size_t size;
|
||||
|
@ -561,6 +570,7 @@ _create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key,
|
|||
memcpy(hkey + size, "//://", 5);
|
||||
size += 5;
|
||||
if (key) ckey = key;
|
||||
else keylen = 6;
|
||||
memcpy(hkey + size, ckey, keylen);
|
||||
size += keylen;
|
||||
if (lo)
|
||||
|
@ -634,7 +644,8 @@ _create_hash_key(char *hkey, const char *path, size_t pathlen, const char *key,
|
|||
}
|
||||
|
||||
EAPI Image_Entry *
|
||||
evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Evas_Image_Load_Opts *lo, int *error)
|
||||
evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key,
|
||||
Evas_Image_Load_Opts *lo, int *error)
|
||||
{
|
||||
size_t size;
|
||||
size_t pathlen;
|
||||
|
@ -659,7 +670,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Ev
|
|||
size = pathlen + keylen + HKEY_LOAD_OPTS_STR_LEN;
|
||||
hkey = alloca(sizeof(char) * size);
|
||||
|
||||
_create_hash_key(hkey, path, pathlen, key, keylen, lo);
|
||||
evas_cache2_image_cache_key_create(hkey, path, pathlen, key, keylen, lo);
|
||||
DBG("Looking at the hash for key '%s'", hkey);
|
||||
|
||||
/* use local var to copy default load options to the image entry */
|
||||
|
@ -697,7 +708,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Ev
|
|||
* of an image at a given key. we wither find it and keep re-reffing
|
||||
* it or we dirty it and get it out */
|
||||
DBG("Entry on inactive hash was invalid (file changed or deleted).");
|
||||
_evas_cache_image_dirty_add(im);
|
||||
_evas_cache2_image_dirty_add(im);
|
||||
im = NULL;
|
||||
}
|
||||
|
||||
|
@ -723,15 +734,15 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Ev
|
|||
if (ok)
|
||||
{
|
||||
/* remove from lru and make it active again */
|
||||
_evas_cache_image_lru_del(im);
|
||||
_evas_cache_image_activ_add(im);
|
||||
_evas_cache2_image_lru_del(im);
|
||||
_evas_cache2_image_activ_add(im);
|
||||
goto on_ok;
|
||||
}
|
||||
DBG("Entry on inactive hash was invalid (file changed or deleted).");
|
||||
/* as avtive cache find - if we match in lru and its invalid, dirty */
|
||||
_evas_cache_image_dirty_add(im);
|
||||
_evas_cache2_image_dirty_add(im);
|
||||
/* this image never used, so it have to be deleted */
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
im = NULL;
|
||||
}
|
||||
if (stat_failed) goto on_stat_error;
|
||||
|
@ -742,7 +753,7 @@ evas_cache2_image_open(Evas_Cache2 *cache, const char *path, const char *key, Ev
|
|||
}
|
||||
_timestamp_build(&tstamp, &st);
|
||||
DBG("Creating a new entry for key '%s'.", hkey);
|
||||
im = _evas_cache_image_entry_new(cache, hkey, &tstamp, path, key,
|
||||
im = _evas_cache2_image_entry_new(cache, hkey, &tstamp, path, key,
|
||||
lo, error);
|
||||
if (!im) goto on_stat_error;
|
||||
|
||||
|
@ -773,7 +784,7 @@ on_stat_error:
|
|||
else
|
||||
*error = EVAS_LOAD_ERROR_GENERIC;
|
||||
|
||||
if (im) _evas_cache_image_entry_delete(cache, im);
|
||||
if (im) _evas_cache2_image_entry_delete(cache, im);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -788,7 +799,8 @@ evas_cache2_image_open_wait(Image_Entry *im)
|
|||
}
|
||||
|
||||
static Image_Entry *
|
||||
_scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h, int dst_w, int dst_h, int smooth)
|
||||
_scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w,
|
||||
int src_h, int dst_w, int dst_h, int smooth)
|
||||
{
|
||||
size_t pathlen, keylen, size;
|
||||
char *hkey;
|
||||
|
@ -816,7 +828,8 @@ _scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h,
|
|||
if (!smooth)
|
||||
{
|
||||
lo.scale_load.smooth = 1;
|
||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
||||
evas_cache2_image_cache_key_create(hkey, im->file, pathlen,
|
||||
im->key, keylen, &lo);
|
||||
|
||||
ret = eina_hash_find(im->cache2->activ, hkey);
|
||||
if (ret) goto found;
|
||||
|
@ -827,7 +840,8 @@ _scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h,
|
|||
lo.scale_load.smooth = smooth;
|
||||
}
|
||||
|
||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
||||
evas_cache2_image_cache_key_create(hkey, im->file, pathlen,
|
||||
im->key, keylen, &lo);
|
||||
|
||||
ret = eina_hash_find(im->cache2->activ, hkey);
|
||||
if (ret) goto found;
|
||||
|
@ -838,8 +852,8 @@ _scaled_image_find(Image_Entry *im, int src_x, int src_y, int src_w, int src_h,
|
|||
if (!ret) return NULL;
|
||||
|
||||
/* Remove from lru and make it active again */
|
||||
_evas_cache_image_lru_del(ret);
|
||||
_evas_cache_image_activ_add(ret);
|
||||
_evas_cache2_image_lru_del(ret);
|
||||
_evas_cache2_image_activ_add(ret);
|
||||
|
||||
found:
|
||||
ret->references++;
|
||||
|
@ -860,6 +874,9 @@ evas_cache2_image_scale_load(Image_Entry *im,
|
|||
int error = EVAS_LOAD_ERROR_NONE;
|
||||
Image_Entry *ret;
|
||||
|
||||
if (!im->cache2)
|
||||
return im;
|
||||
|
||||
if (!smooth && im->scale_hint != EVAS_IMAGE_SCALE_HINT_STATIC)
|
||||
goto parent_out;
|
||||
|
||||
|
@ -896,15 +913,16 @@ evas_cache2_image_scale_load(Image_Entry *im,
|
|||
lo.scale_load.smooth = smooth;
|
||||
lo.scale_load.scale_hint = im->scale_hint;
|
||||
|
||||
_create_hash_key(hkey, im->file, pathlen, im->key, keylen, &lo);
|
||||
evas_cache2_image_cache_key_create(hkey, im->file, pathlen,
|
||||
im->key, keylen, &lo);
|
||||
|
||||
ret = _evas_cache_image_entry_new(im->cache2, hkey, NULL, im->file, im->key,
|
||||
ret = _evas_cache2_image_entry_new(im->cache2, hkey, NULL, im->file, im->key,
|
||||
&lo, &error);
|
||||
if (error != EVAS_LOAD_ERROR_NONE)
|
||||
{
|
||||
ERR("Failed to create scale image entry with error code %d.", error);
|
||||
|
||||
if (ret) _evas_cache_image_entry_delete(im->cache2, ret);
|
||||
if (ret) _evas_cache2_image_entry_delete(im->cache2, ret);
|
||||
goto parent_out;
|
||||
}
|
||||
|
||||
|
@ -948,13 +966,13 @@ evas_cache2_image_close(Image_Entry *im)
|
|||
if (references > 0)
|
||||
return;
|
||||
|
||||
if (im->flags.dirty)
|
||||
if (im->flags.dirty || im->animated.animated)
|
||||
{
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
return;
|
||||
}
|
||||
|
||||
_evas_cache_image_lru_add(im);
|
||||
_evas_cache2_image_lru_add(im);
|
||||
if (cache)
|
||||
evas_cache2_flush(cache);
|
||||
}
|
||||
|
@ -965,7 +983,10 @@ evas_cache2_image_load_data(Image_Entry *ie)
|
|||
int error = EVAS_LOAD_ERROR_NONE;
|
||||
|
||||
if ((ie->flags.loaded) && (!ie->animated.animated))
|
||||
return error;
|
||||
{
|
||||
evas_cserve2_image_hit(ie);
|
||||
return EVAS_LOAD_ERROR_NONE;
|
||||
}
|
||||
|
||||
ie->flags.in_progress = EINA_TRUE;
|
||||
|
||||
|
@ -976,10 +997,10 @@ evas_cache2_image_load_data(Image_Entry *ie)
|
|||
error = evas_cserve2_image_load_data_wait(ie);
|
||||
|
||||
RGBA_Image *im = (RGBA_Image *)ie;
|
||||
DBG("try cserve2 image data '%s' '%s' loaded!",
|
||||
ie->file, ie->key ? ie->key : "");
|
||||
if ((error == CSERVE2_NONE) && im->image.data)
|
||||
{
|
||||
DBG("try cserve2 image data '%s' '%s' loaded!",
|
||||
ie->file, ie->key ? ie->key : "");
|
||||
error = EVAS_LOAD_ERROR_NONE;
|
||||
}
|
||||
else
|
||||
|
@ -1060,7 +1081,7 @@ evas_cache2_image_writable(Image_Entry *im)
|
|||
if (!im->cache_key)
|
||||
{
|
||||
if (!im->flags.dirty)
|
||||
_evas_cache_image_dirty_add(im);
|
||||
_evas_cache2_image_dirty_add(im);
|
||||
return im;
|
||||
}
|
||||
|
||||
|
@ -1075,7 +1096,7 @@ evas_cache2_image_writable(Image_Entry *im)
|
|||
|
||||
on_error:
|
||||
if (im2)
|
||||
_evas_cache_image_entry_delete(cache, im2);
|
||||
_evas_cache2_image_entry_delete(cache, im2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1088,7 +1109,7 @@ evas_cache2_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigne
|
|||
if (!im->cache_key)
|
||||
{
|
||||
if (!im->flags.dirty)
|
||||
_evas_cache_image_dirty_add(im);
|
||||
_evas_cache2_image_dirty_add(im);
|
||||
im2 = im;
|
||||
}
|
||||
else
|
||||
|
@ -1123,7 +1144,7 @@ evas_cache2_flush(Evas_Cache2 *cache)
|
|||
|
||||
im = (Image_Entry *)cache->lru->last;
|
||||
DBG("Remove unused entry from cache.");
|
||||
_evas_cache_image_entry_delete(cache, im);
|
||||
_evas_cache2_image_entry_delete(cache, im);
|
||||
}
|
||||
|
||||
return cache->usage;
|
||||
|
|
|
@ -66,6 +66,7 @@ EAPI void evas_cache2_image_close(Image_Entry *im);
|
|||
EAPI int evas_cache2_image_load_data(Image_Entry *ie);
|
||||
EAPI void evas_cache2_image_unload_data(Image_Entry *im);
|
||||
EAPI void evas_cache2_image_preload_data(Image_Entry *im, const void *target);
|
||||
EAPI void evas_cache2_image_cache_key_create(char *hkey, const char *path, size_t pathlen, const char *key, size_t keylen, const Evas_Image_Load_Opts *lo);
|
||||
|
||||
EAPI DATA32 * evas_cache2_image_pixels(Image_Entry *im);
|
||||
EAPI Image_Entry * evas_cache2_image_writable(Image_Entry *im);
|
||||
|
@ -75,6 +76,7 @@ EAPI Image_Entry * evas_cache2_image_size_set(Image_Entry *im, unsigned int w, u
|
|||
EAPI Image_Entry * evas_cache2_image_dirty(Image_Entry *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
|
||||
EAPI Image_Entry * evas_cache2_image_empty(Evas_Cache2 *cache);
|
||||
EAPI void evas_cache2_image_surface_alloc(Image_Entry *ie, int w, int h);
|
||||
EAPI Eina_Bool evas_cache2_image_cached(Image_Entry *ie);
|
||||
|
||||
EAPI int evas_cache2_flush(Evas_Cache2 *cache);
|
||||
EAPI void evas_cache2_limit_set(Evas_Cache2 *cache, int limit);
|
||||
|
|
|
@ -55,7 +55,11 @@ evas_init(void)
|
|||
if (!evas_async_events_init())
|
||||
goto shutdown_module;
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (getenv("EVAS_CSERVE2")) evas_cserve2_init();
|
||||
{
|
||||
const char *env;
|
||||
env = getenv("EVAS_CSERVE2");
|
||||
if (env && atoi(env)) evas_cserve2_init();
|
||||
}
|
||||
#endif
|
||||
_evas_preload_thread_init();
|
||||
|
||||
|
@ -95,6 +99,11 @@ evas_shutdown(void)
|
|||
EINA_LOG_STATE_START,
|
||||
EINA_LOG_STATE_SHUTDOWN);
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cserve2_shutdown();
|
||||
#endif
|
||||
|
||||
eina_cow_del(evas_object_proxy_cow);
|
||||
eina_cow_del(evas_object_map_cow);
|
||||
eina_cow_del(evas_object_state_cow);
|
||||
|
|
|
@ -3998,53 +3998,15 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
|
|||
(o->cur->border.b == 0) &&
|
||||
(o->cur->border.fill != 0))
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
Image_Entry *ie;
|
||||
void *data = pixels;
|
||||
int w = imagew, h = imageh;
|
||||
Eina_Bool mustclose = EINA_FALSE;
|
||||
|
||||
ie = evas_cache2_image_scale_load
|
||||
((Image_Entry *)pixels,
|
||||
0, 0,
|
||||
imagew, imageh,
|
||||
iw, ih, o->cur->smooth_scale);
|
||||
if (ie != &((RGBA_Image *)pixels)->cache_entry)
|
||||
{
|
||||
data = ie;
|
||||
w = iw;
|
||||
h = ih;
|
||||
mustclose = EINA_TRUE;
|
||||
}
|
||||
|
||||
_draw_image
|
||||
(obj, output, context, surface, data,
|
||||
0, 0,
|
||||
w, h,
|
||||
obj->cur->geometry.x + ix + x,
|
||||
obj->cur->geometry.y + iy + y,
|
||||
iw, ih,
|
||||
o->cur->smooth_scale,
|
||||
do_async);
|
||||
|
||||
if (mustclose)
|
||||
evas_cache2_image_close(ie);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_draw_image
|
||||
(obj, output, context, surface, pixels,
|
||||
0, 0,
|
||||
imagew, imageh,
|
||||
obj->cur->geometry.x + ix + x,
|
||||
obj->cur->geometry.y + iy + y,
|
||||
iw, ih,
|
||||
o->cur->smooth_scale,
|
||||
do_async);
|
||||
}
|
||||
_draw_image
|
||||
(obj, output, context, surface, pixels,
|
||||
0, 0,
|
||||
imagew, imageh,
|
||||
obj->cur->geometry.x + ix + x,
|
||||
obj->cur->geometry.y + iy + y,
|
||||
iw, ih,
|
||||
o->cur->smooth_scale,
|
||||
do_async);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -66,6 +66,8 @@ void
|
|||
evas_object_inform_call_image_preloaded(Evas_Object *eo_obj)
|
||||
{
|
||||
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJ_CLASS);
|
||||
EINA_SAFETY_ON_NULL_RETURN(obj);
|
||||
|
||||
if (!_evas_object_image_preloading_get(eo_obj)) return;
|
||||
_evas_object_image_preloading_check(eo_obj);
|
||||
_evas_object_image_preloading_set(eo_obj, 0);
|
||||
|
|
|
@ -1571,7 +1571,7 @@ static Eina_Bool
|
|||
_drop_image_cache_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(data))
|
||||
evas_cache2_image_close((Image_Entry *)data);
|
||||
else
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
#include "evas_font_ot.h"
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
#include "../cserve2/evas_cs2_private.h"
|
||||
#endif
|
||||
|
||||
struct _Evas_Glyph
|
||||
{
|
||||
RGBA_Font_Glyph *fg;
|
||||
|
@ -227,6 +231,19 @@ evas_common_font_rgba_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
|
|||
void
|
||||
evas_common_font_glyphs_ref(Evas_Glyph_Array *array)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get() && !array->refcount)
|
||||
{
|
||||
Eina_Iterator *iter;
|
||||
Evas_Glyph *glyph;
|
||||
|
||||
iter = eina_inarray_iterator_new(array->array);
|
||||
EINA_ITERATOR_FOREACH(iter, glyph)
|
||||
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_TRUE);
|
||||
eina_iterator_free(iter);
|
||||
}
|
||||
#endif
|
||||
|
||||
array->refcount++;
|
||||
}
|
||||
|
||||
|
@ -235,6 +252,19 @@ evas_common_font_glyphs_unref(Evas_Glyph_Array *array)
|
|||
{
|
||||
if (--array->refcount) return;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
Eina_Iterator *iter;
|
||||
Evas_Glyph *glyph;
|
||||
|
||||
iter = eina_inarray_iterator_new(array->array);
|
||||
EINA_ITERATOR_FOREACH(iter, glyph)
|
||||
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_FALSE);
|
||||
eina_iterator_free(iter);
|
||||
}
|
||||
#endif
|
||||
|
||||
eina_inarray_free(array->array);
|
||||
evas_common_font_int_unref(array->fi);
|
||||
free(array);
|
||||
|
@ -274,6 +304,18 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
|
|||
if (text_props->len < unit) unit = text_props->len;
|
||||
if (text_props->glyphs && text_props->glyphs->refcount == 1)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
Eina_Iterator *iter;
|
||||
Evas_Glyph *glyph;
|
||||
|
||||
iter = eina_inarray_iterator_new(text_props->glyphs->array);
|
||||
EINA_ITERATOR_FOREACH(iter, glyph)
|
||||
evas_cserve2_font_glyph_ref(glyph->fg->glyph_out, EINA_FALSE);
|
||||
eina_iterator_free(iter);
|
||||
}
|
||||
#endif
|
||||
glyphs = text_props->glyphs->array;
|
||||
glyphs->len = 0;
|
||||
reused_glyphs = EINA_TRUE;
|
||||
|
@ -304,7 +346,16 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
|
|||
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, idx);
|
||||
if (!fg) continue;
|
||||
if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
|
||||
if (!evas_common_font_int_cache_glyph_render(fg))
|
||||
{
|
||||
fg = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
evas_cserve2_font_glyph_ref(fg->glyph_out, EINA_TRUE);
|
||||
#endif
|
||||
|
||||
glyph = eina_inarray_grow(glyphs, 1);
|
||||
if (!glyph) goto error;
|
||||
|
|
|
@ -548,12 +548,21 @@ evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *fg)
|
|||
fg->glyph_out = evas_cserve2_font_glyph_bitmap_get(fi->cs2_handler,
|
||||
fg->index,
|
||||
fg->fi->hinting);
|
||||
if (fg->glyph_out)
|
||||
return EINA_TRUE;
|
||||
if (!fg->glyph_out)
|
||||
{
|
||||
if (!fi->fash) fi->fash = _fash_gl_new();
|
||||
if (fi->fash) _fash_gl_add(fi->fash, fg->index, (void *)(-1));
|
||||
free(fg);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* no cserve2 case */
|
||||
if (fg->glyph_out)
|
||||
return EINA_TRUE;
|
||||
|
||||
FTLOCK();
|
||||
error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
|
||||
if (error)
|
||||
|
|
|
@ -243,18 +243,10 @@ evas_common_load_rgba_image_module_from_file(Image_Entry *ie)
|
|||
struct evas_image_foreach_loader_data fdata;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
ERR("This function shouldn't be called anymore!");
|
||||
// DBG("try cserve2 '%s' '%s'", ie->file, ie->key ? ie->key : "");
|
||||
// if (evas_cserve2_image_load(ie, ie->file, ie->key, &(ie->load_opts)))
|
||||
// {
|
||||
// DBG("try cserve2 '%s' '%s' loaded!",
|
||||
// ie->file, ie->key ? ie->key : "");
|
||||
// return EVAS_LOAD_ERROR_NONE;
|
||||
// }
|
||||
}
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(ie))
|
||||
CRIT("This function shouldn't be called anymore!");
|
||||
#endif
|
||||
|
||||
if (ie->f)
|
||||
{
|
||||
len = strlen(eina_file_filename_get(ie->f));
|
||||
|
@ -368,25 +360,8 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
|
|||
if ((ie->flags.loaded) && (!ie->animated.animated)) return EVAS_LOAD_ERROR_GENERIC;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (ie->data1)
|
||||
{
|
||||
ERR("This function shouldn't be called anymore!");
|
||||
// DBG("try cserve2 image data '%s' '%s'",
|
||||
// ie->file, ie->key ? ie->key : "");
|
||||
// if (evas_cserve2_image_data_load(ie))
|
||||
// {
|
||||
// RGBA_Image *im = (RGBA_Image *)ie;
|
||||
// im->image.data = evas_cserve2_image_data_get(ie);
|
||||
// DBG("try cserve2 image data '%s' '%s' loaded!",
|
||||
// ie->file, ie->key ? ie->key : "");
|
||||
// if (im->image.data)
|
||||
// {
|
||||
// im->image.no_free = 1;
|
||||
// return EVAS_LOAD_ERROR_NONE;
|
||||
// }
|
||||
// }
|
||||
// return EVAS_LOAD_ERROR_GENERIC;
|
||||
}
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(ie))
|
||||
CRIT("This function shouldn't be called anymore!");
|
||||
#endif
|
||||
|
||||
if (!ie->info.module) return EVAS_LOAD_ERROR_GENERIC;
|
||||
|
|
|
@ -663,7 +663,7 @@ evas_common_rgba_image_scalecache_do_cbs(Image_Entry *ie, RGBA_Image *dst,
|
|||
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||
evas_cache2_image_load_data(&im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
|
@ -759,6 +759,26 @@ evas_common_rgba_image_scalecache_do_cbs(Image_Entry *ie, RGBA_Image *dst,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (sci->populate_me && (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||
&& evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||
{
|
||||
RGBA_Image *im2 = (RGBA_Image *) evas_cache2_image_scale_load
|
||||
(&im->cache_entry, src_region_x, src_region_y,
|
||||
src_region_w, src_region_h, dst_region_w, dst_region_h, smooth);
|
||||
SLKL(cache_lock);
|
||||
if (im2 != im)
|
||||
{
|
||||
sci->im = im2;
|
||||
sci->populate_me = 0;
|
||||
cache_list = eina_inlist_append(cache_list, (Eina_Inlist *)sci);
|
||||
didpop = 1;
|
||||
}
|
||||
SLKU(cache_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sci->populate_me)
|
||||
{
|
||||
// INF("##! populate!");
|
||||
|
|
|
@ -23,6 +23,7 @@ typedef enum {
|
|||
CSERVE2_FONT_GLYPHS_USED,
|
||||
CSERVE2_STATS,
|
||||
CSERVE2_FONT_DEBUG,
|
||||
CSERVE2_INDEX_LIST,
|
||||
CSERVE2_ERROR
|
||||
} Message_Type;
|
||||
|
||||
|
@ -38,6 +39,7 @@ typedef enum {
|
|||
CSERVE2_LOADER_DIED,
|
||||
CSERVE2_LOADER_EXEC_ERR,
|
||||
CSERVE2_INVALID_CACHE, // invalid cserve cache entry
|
||||
CSERVE2_NOT_LOADED,
|
||||
CSERVE2_FILE_CHANGED,
|
||||
CSERVE2_REQUEST_CANCEL
|
||||
} Error_Type;
|
||||
|
@ -72,6 +74,7 @@ struct _Msg_Opened {
|
|||
int loop_count;
|
||||
int loop_hint; /* include Evas.h? Copy the enum around? */
|
||||
Eina_Bool alpha : 1;
|
||||
Eina_Bool animated : 1;
|
||||
} image;
|
||||
};
|
||||
|
||||
|
@ -88,6 +91,10 @@ struct _Msg_Loaded {
|
|||
int mmap_size;
|
||||
int image_size;
|
||||
} shm;
|
||||
struct {
|
||||
unsigned int w, h; // Real dimensions of this image. May differ from Msg_Opened::image::{w,h} after scaling.
|
||||
} image;
|
||||
Eina_Bool alpha : 1;
|
||||
Eina_Bool alpha_sparse : 1;
|
||||
};
|
||||
|
||||
|
@ -183,7 +190,6 @@ struct _Msg_Font_Glyphs_Request {
|
|||
*/
|
||||
struct _Msg_Font_Glyphs_Loaded {
|
||||
Msg_Base base;
|
||||
unsigned int ncaches;
|
||||
};
|
||||
|
||||
struct _Msg_Stats {
|
||||
|
@ -224,13 +230,14 @@ struct _Msg_Stats {
|
|||
} images;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* @struct _Msg_Font_Debug
|
||||
*
|
||||
* Message from server containing all font cache info.
|
||||
*
|
||||
* Content of the message follows:
|
||||
*
|
||||
* * char fonts_index_path[64]
|
||||
* * number of font entries;
|
||||
* * each font entry:
|
||||
* - unsigned int filelen
|
||||
|
@ -241,15 +248,15 @@ struct _Msg_Stats {
|
|||
* - unsigned int size;
|
||||
* - unsigned int dpi;
|
||||
* - unsigned int unused;
|
||||
* - ncaches:
|
||||
* - each cache:
|
||||
* * usigned int shmnamelen;
|
||||
* * const char shmname;
|
||||
* * unsigned int size;
|
||||
* * unsigned int usage;
|
||||
* * unsigned int nglyphs;
|
||||
* * each glyph:
|
||||
* - const char glyph_data_shm[64];
|
||||
* - const char glyph_mempool_shm[64];
|
||||
* - unsigned int nglyphs;
|
||||
* - each glyph: Glyph_Data struct
|
||||
* - unsigned int id;
|
||||
* - unsigned int refcount;
|
||||
* - unsigned int index;
|
||||
* - unsigned int shm_id; // shared string id
|
||||
* - unsigned int buffer_id;
|
||||
* - unsigned int offset;
|
||||
* - unsigned int size;
|
||||
* - unsigned int rows;
|
||||
|
@ -260,6 +267,136 @@ struct _Msg_Stats {
|
|||
*/
|
||||
struct _Msg_Font_Debug {
|
||||
Msg_Base base;
|
||||
char fonts_index_path[64];
|
||||
int nfonts;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Msg_Index_List struct
|
||||
*
|
||||
* Message sent from the server, without request from the client,
|
||||
* to inform all clients of the shared index files. Contains the paths
|
||||
* to the latest File, Image and Font index shm.
|
||||
*
|
||||
* The paths contain only the filename used in the call to shm_open.
|
||||
* All strings must be null-terminated.
|
||||
*/
|
||||
struct _Msg_Index_List {
|
||||
Msg_Base base;
|
||||
int generation_id;
|
||||
char strings_index_path[64];
|
||||
char strings_entries_path[64];
|
||||
char files_index_path[64];
|
||||
char images_index_path[64];
|
||||
char fonts_index_path[64];
|
||||
};
|
||||
|
||||
typedef struct _Shm_Object Shm_Object;
|
||||
typedef struct _Index_Entry Index_Entry;
|
||||
typedef struct _File_Data File_Data;
|
||||
typedef struct _Image_Data Image_Data;
|
||||
typedef struct _Font_Data Font_Data;
|
||||
typedef struct _Glyph_Data Glyph_Data;
|
||||
typedef struct _Shared_Array_Header Shared_Array_Header;
|
||||
typedef int string_t;
|
||||
#define SHMOBJECT unsigned int id; unsigned int refcount
|
||||
|
||||
struct _Shared_Array_Header {
|
||||
int32_t tag;
|
||||
int32_t generation_id;
|
||||
int32_t elemsize;
|
||||
int32_t count;
|
||||
int32_t emptyidx;
|
||||
int32_t sortedidx;
|
||||
int32_t _reserved1;
|
||||
int32_t _reserved2;
|
||||
};
|
||||
|
||||
struct _Shm_Object {
|
||||
SHMOBJECT;
|
||||
};
|
||||
|
||||
#define STRING_INDEX_ARRAY_TAG ('S' | 'T' << 8 | 'R' << 16 | 'N' << 24)
|
||||
#define STRING_MEMPOOL_FAKETAG ('S' | 'T' << 8 | 'R' << 16 | 'M' << 24)
|
||||
struct _Index_Entry {
|
||||
SHMOBJECT;
|
||||
// Block entry
|
||||
int32_t length;
|
||||
int32_t offset;
|
||||
int32_t shmid;
|
||||
};
|
||||
|
||||
#define FILE_DATA_ARRAY_TAG ('F' | 'I' << 8 | 'L' << 16 | 'E' << 24)
|
||||
struct _File_Data {
|
||||
SHMOBJECT;
|
||||
// Hash entry elements (see Evas_Image_Load_Opts)
|
||||
string_t path;
|
||||
string_t key;
|
||||
struct {
|
||||
struct {
|
||||
unsigned int x, y, w, h;
|
||||
} region;
|
||||
double dpi;
|
||||
unsigned int w, h;
|
||||
int scale_down_by;
|
||||
Eina_Bool orientation;
|
||||
} lo;
|
||||
// Properties set after opening the file
|
||||
string_t loader_data; // Can also be set during open (force this loader)
|
||||
int w, h;
|
||||
int frame_count;
|
||||
int loop_count;
|
||||
int loop_hint;
|
||||
Eina_Bool alpha : 1;
|
||||
Eina_Bool invalid : 1;
|
||||
Eina_Bool valid : 1;
|
||||
Eina_Bool animated : 1;
|
||||
};
|
||||
|
||||
#define IMAGE_DATA_ARRAY_TAG ('I' | 'M' << 8 | 'A' << 16 | 'G' << 24)
|
||||
struct _Image_Data {
|
||||
SHMOBJECT;
|
||||
uint32_t file_id;
|
||||
string_t shm_id;
|
||||
Evas_Image_Load_Opts opts;
|
||||
uint32_t w, h;
|
||||
Eina_Bool alpha : 1;
|
||||
Eina_Bool alpha_sparse : 1;
|
||||
Eina_Bool unused : 1;
|
||||
Eina_Bool doload : 1;
|
||||
Eina_Bool valid : 1;
|
||||
};
|
||||
|
||||
#define FONT_DATA_ARRAY_TAG ('F' | 'O' << 8 | 'N' << 16 | 'T' << 24)
|
||||
struct _Font_Data {
|
||||
SHMOBJECT;
|
||||
string_t name;
|
||||
string_t file;
|
||||
string_t glyph_index_shm;
|
||||
string_t mempool_shm;
|
||||
uint32_t rend_flags;
|
||||
uint32_t size;
|
||||
uint32_t dpi;
|
||||
};
|
||||
|
||||
#define GLYPH_DATA_ARRAY_TAG ('G' | 'L' << 8 | 'P' << 16 | 'H' << 24)
|
||||
struct _Glyph_Data {
|
||||
// Index_Entry
|
||||
SHMOBJECT;
|
||||
int32_t length;
|
||||
int32_t offset;
|
||||
int32_t shmid;
|
||||
// Glyph data stuff
|
||||
uint32_t index;
|
||||
string_t mempool_id; // TODO: Merge with shmid? (Internally impossible atm)
|
||||
uint32_t buffer_id;
|
||||
uint32_t size;
|
||||
uint32_t rows;
|
||||
uint32_t width;
|
||||
uint32_t pitch;
|
||||
uint32_t num_grays;
|
||||
uint32_t pixel_mode;
|
||||
uint32_t hint;
|
||||
};
|
||||
|
||||
struct _Msg_Error {
|
||||
|
@ -282,6 +419,7 @@ typedef struct _Msg_Font_Glyphs_Loaded Msg_Font_Glyphs_Loaded;
|
|||
typedef struct _Msg_Stats Msg_Stats;
|
||||
typedef struct _Msg_Font_Debug Msg_Font_Debug;
|
||||
typedef struct _Msg_Error Msg_Error;
|
||||
typedef struct _Msg_Index_List Msg_Index_List;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,4 +20,13 @@ evas_cserve2_image_data_get(Image_Entry *ie)
|
|||
return dentry->shm.data;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
evas_cserve2_image_hit(Image_Entry *ie)
|
||||
{
|
||||
Data_Entry *dentry = ie->data2;
|
||||
|
||||
if (!dentry) return 0;
|
||||
return ++dentry->hit_count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,12 +2,21 @@
|
|||
#define EVAS_CS2_PRIVATE_H 1
|
||||
|
||||
#include "evas_common_private.h"
|
||||
#include "evas_cs2.h"
|
||||
|
||||
struct _Data_Entry {
|
||||
#define SHARED_BUFFER_PATH_MAX 64
|
||||
typedef struct _Data_Entry Data_Entry;
|
||||
typedef struct _Font_Entry Font_Entry;
|
||||
typedef struct _Index_Table Index_Table;
|
||||
typedef struct _Shared_Index Shared_Index;
|
||||
typedef struct _Shared_Buffer Shared_Buffer;
|
||||
|
||||
struct _Data_Entry
|
||||
{
|
||||
unsigned int image_id;
|
||||
unsigned int hit_count;
|
||||
void (*preloaded_cb)(void *, Eina_Bool);
|
||||
struct {
|
||||
const char *path;
|
||||
int mmap_offset;
|
||||
int use_offset;
|
||||
int mmap_size;
|
||||
|
@ -17,8 +26,48 @@ struct _Data_Entry {
|
|||
} shm;
|
||||
};
|
||||
|
||||
typedef struct _Data_Entry Data_Entry;
|
||||
typedef struct _Font_Entry Font_Entry;
|
||||
struct _Shared_Index
|
||||
{
|
||||
char path[SHARED_BUFFER_PATH_MAX];
|
||||
int generation_id;
|
||||
Eina_File *f;
|
||||
union
|
||||
{
|
||||
const Shared_Array_Header *header;
|
||||
char *data;
|
||||
};
|
||||
union
|
||||
{
|
||||
const char *p; // Random access
|
||||
const Index_Entry *index;
|
||||
const Image_Data *idata;
|
||||
const File_Data *filedata;
|
||||
const Font_Data *fontdata;
|
||||
const Glyph_Data *gldata;
|
||||
} entries;
|
||||
int count;
|
||||
Eina_Hash *entries_by_hkey;
|
||||
int last_entry_in_hash;
|
||||
};
|
||||
|
||||
struct _Shared_Buffer
|
||||
{
|
||||
char path[SHARED_BUFFER_PATH_MAX];
|
||||
Eina_File *f;
|
||||
char *data;
|
||||
int size;
|
||||
EINA_REFCOUNT;
|
||||
};
|
||||
|
||||
struct _Index_Table
|
||||
{
|
||||
int generation_id;
|
||||
Shared_Buffer strings_entries;
|
||||
Shared_Index strings_index;
|
||||
Shared_Index files;
|
||||
Shared_Index images;
|
||||
Shared_Index fonts;
|
||||
};
|
||||
|
||||
int evas_cserve2_init(void);
|
||||
int evas_cserve2_shutdown(void);
|
||||
|
@ -33,6 +82,7 @@ Eina_Bool evas_cserve2_image_preload(Image_Entry *ie, void (*preloaded_cb)(void
|
|||
void evas_cserve2_dispatch(void);
|
||||
|
||||
void *evas_cserve2_image_data_get(Image_Entry *ie);
|
||||
unsigned int evas_cserve2_image_hit(Image_Entry *ie);
|
||||
|
||||
Font_Entry *evas_cserve2_font_load(const char *source, const char *name, int size, int dpi, Font_Rend_Flags wanted_rend);
|
||||
EAPI int evas_cserve2_font_load_wait(Font_Entry *fe);
|
||||
|
@ -40,4 +90,5 @@ void evas_cserve2_font_free(Font_Entry *fe);
|
|||
Eina_Bool evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
|
||||
Eina_Bool evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints) EINA_WARN_UNUSED_RESULT;
|
||||
RGBA_Font_Glyph_Out *evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
|
||||
void evas_cserve2_font_glyph_ref(RGBA_Font_Glyph_Out *glyph, Eina_Bool incref);
|
||||
#endif
|
||||
|
|
|
@ -56,6 +56,8 @@ fash_gl_free(Fash_Glyph2 *fash)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!fash) return;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
if (fash->bucket[i]) _fash_gl2_free(fash, fash->bucket[i]);
|
||||
free(fash);
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "evas_gl_private.h"
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
#include "evas_cs2_private.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
evas_gl_common_image_alloc_ensure(Evas_GL_Image *im)
|
||||
{
|
||||
|
@ -16,7 +20,15 @@ evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc)
|
|||
|
||||
EINA_LIST_FOREACH(gc->shared->images, l, im)
|
||||
{
|
||||
if (im->im) evas_cache_image_unload_data(&im->im->cache_entry);
|
||||
if (im->im)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_unload_data(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_unload_data(&im->im->cache_entry);
|
||||
}
|
||||
if (im->tex)
|
||||
{
|
||||
if (!im->tex->pt->dyn.img)
|
||||
|
@ -141,7 +153,12 @@ _evas_gl_common_image(Evas_Engine_GL_Context *gc, RGBA_Image *im_im, Evas_Image_
|
|||
im = calloc(1, sizeof(Evas_GL_Image));
|
||||
if (!im)
|
||||
{
|
||||
evas_cache_image_drop(&(im_im->cache_entry));
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im_im->cache_entry))
|
||||
evas_cache2_image_close(&(im_im->cache_entry));
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&(im_im->cache_entry));
|
||||
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -163,6 +180,26 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch
|
|||
{
|
||||
RGBA_Image *im_im;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
im_im = (RGBA_Image *) evas_cache2_image_open
|
||||
(evas_common_image_cache2_get(), file, key, lo, error);
|
||||
if (im_im)
|
||||
{
|
||||
*error = evas_cache2_image_open_wait(&im_im->cache_entry);
|
||||
if ((*error != EVAS_LOAD_ERROR_NONE)
|
||||
&& im_im->cache_entry.animated.animated)
|
||||
{
|
||||
evas_cache2_image_close(&im_im->cache_entry);
|
||||
im_im = NULL;
|
||||
}
|
||||
else
|
||||
return _evas_gl_common_image(gc, im_im, lo, error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
im_im = evas_common_load_image_from_file(file, key, lo, error);
|
||||
if (!im_im) return NULL;
|
||||
|
||||
|
@ -174,6 +211,26 @@ evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *
|
|||
{
|
||||
RGBA_Image *im_im;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get() && !eina_file_virtual(f))
|
||||
{
|
||||
im_im = (RGBA_Image *) evas_cache2_image_open
|
||||
(evas_common_image_cache2_get(), eina_file_filename_get(f), key, lo, error);
|
||||
if (im_im)
|
||||
{
|
||||
*error = evas_cache2_image_open_wait(&im_im->cache_entry);
|
||||
if ((*error != EVAS_LOAD_ERROR_NONE)
|
||||
&& im_im->cache_entry.animated.animated)
|
||||
{
|
||||
evas_cache2_image_close(&im_im->cache_entry);
|
||||
im_im = NULL;
|
||||
}
|
||||
else
|
||||
return _evas_gl_common_image(gc, im_im, lo, error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
im_im = evas_common_load_image_from_mmap(f, key, lo, error);
|
||||
if (!im_im) return NULL;
|
||||
|
||||
|
@ -341,7 +398,12 @@ evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha)
|
|||
im->alpha = alpha;
|
||||
if (!im->im) return im;
|
||||
evas_gl_common_image_alloc_ensure(im);
|
||||
evas_cache_image_load_data(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_load_data(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_load_data(&im->im->cache_entry);
|
||||
im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
|
||||
|
||||
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
||||
|
@ -376,7 +438,12 @@ evas_gl_common_image_native_enable(Evas_GL_Image *im)
|
|||
}
|
||||
if (im->im)
|
||||
{
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_close(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
im->im = NULL;
|
||||
}
|
||||
if (im->tex)
|
||||
|
@ -395,7 +462,12 @@ evas_gl_common_image_native_disable(Evas_GL_Image *im)
|
|||
{
|
||||
if (im->im)
|
||||
{
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (!evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_close(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
im->im = NULL;
|
||||
}
|
||||
if (im->tex)
|
||||
|
@ -451,7 +523,12 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
|
|||
}
|
||||
if (im->im)
|
||||
{
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_close(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
im->im = NULL;
|
||||
}
|
||||
if (im->tex)
|
||||
|
@ -466,7 +543,12 @@ evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
|
|||
{
|
||||
if (im->im)
|
||||
{
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_close(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
im->im = NULL;
|
||||
}
|
||||
if (im->tex)
|
||||
|
@ -510,7 +592,15 @@ evas_gl_common_image_free(Evas_GL_Image *im)
|
|||
{
|
||||
if (_evas_gl_image_cache_add(im)) return;
|
||||
}
|
||||
if (im->im) evas_cache_image_drop(&im->im->cache_entry);
|
||||
if (im->im)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
evas_cache2_image_close(&im->im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
evas_cache_image_drop(&im->im->cache_entry);
|
||||
}
|
||||
if (im->tex) evas_gl_common_texture_free(im->tex, EINA_TRUE);
|
||||
|
||||
free(im);
|
||||
|
@ -549,7 +639,12 @@ evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, un
|
|||
if (im->im)
|
||||
{
|
||||
evas_gl_common_image_alloc_ensure(im);
|
||||
im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
im->im = (RGBA_Image *)evas_cache2_image_dirty(&im->im->cache_entry, x, y, w, h);
|
||||
else
|
||||
#endif
|
||||
im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
|
||||
}
|
||||
im->dirty = 1;
|
||||
}
|
||||
|
@ -588,16 +683,38 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
|
|||
if ((im->tex) &&
|
||||
((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data)))
|
||||
{
|
||||
evas_cache_image_load_data(&im->im->cache_entry);
|
||||
evas_gl_common_texture_update(im->tex, im->im);
|
||||
evas_cache_image_unload_data(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
{
|
||||
evas_cache2_image_load_data(&im->im->cache_entry);
|
||||
evas_gl_common_texture_update(im->tex, im->im);
|
||||
evas_cache2_image_unload_data(&im->im->cache_entry);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
evas_cache_image_load_data(&im->im->cache_entry);
|
||||
evas_gl_common_texture_update(im->tex, im->im);
|
||||
evas_cache_image_unload_data(&im->im->cache_entry);
|
||||
}
|
||||
ie->flags.updated_data = 0;
|
||||
}
|
||||
if (!im->tex)
|
||||
{
|
||||
evas_cache_image_load_data(&im->im->cache_entry);
|
||||
im->tex = evas_gl_common_texture_new(gc, im->im);
|
||||
evas_cache_image_unload_data(&im->im->cache_entry);
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cache2_image_cached(&im->im->cache_entry))
|
||||
{
|
||||
evas_cache2_image_load_data(&im->im->cache_entry);
|
||||
im->tex = evas_gl_common_texture_new(gc, im->im);
|
||||
evas_cache2_image_unload_data(&im->im->cache_entry);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
evas_cache_image_load_data(&im->im->cache_entry);
|
||||
im->tex = evas_gl_common_texture_new(gc, im->im);
|
||||
evas_cache_image_unload_data(&im->im->cache_entry);
|
||||
}
|
||||
}
|
||||
im->dirty = 0;
|
||||
if (!im->tex) return;
|
||||
|
|
|
@ -949,10 +949,19 @@ eng_image_load(void *data EINA_UNUSED, const char *file, const char *key, int *e
|
|||
ie = evas_cache2_image_open(evas_common_image_cache2_get(),
|
||||
file, key, lo, error);
|
||||
if (ie)
|
||||
*error = evas_cache2_image_open_wait(ie);
|
||||
{
|
||||
*error = evas_cache2_image_open_wait(ie);
|
||||
if ((*error != EVAS_LOAD_ERROR_NONE) && ie->animated.animated)
|
||||
{
|
||||
evas_cache2_image_close(ie);
|
||||
goto use_local_cache;
|
||||
}
|
||||
}
|
||||
return ie;
|
||||
}
|
||||
use_local_cache:
|
||||
#endif
|
||||
|
||||
return evas_common_load_image_from_file(file, key, lo, error);
|
||||
}
|
||||
|
||||
|
@ -962,16 +971,25 @@ eng_image_mmap(void *data EINA_UNUSED, Eina_File *f, const char *key, int *error
|
|||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
#ifdef EVAS_CSERVE2
|
||||
// FIXME: Need to pass fd to make that useful, so just get the filename for now.
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && !eina_file_virtual(f))
|
||||
{
|
||||
Image_Entry *ie;
|
||||
ie = evas_cache2_image_open(evas_common_image_cache2_get(),
|
||||
eina_file_filename_get(f), key, lo, error);
|
||||
if (ie)
|
||||
*error = evas_cache2_image_open_wait(ie);
|
||||
{
|
||||
*error = evas_cache2_image_open_wait(ie);
|
||||
if ((*error != EVAS_LOAD_ERROR_NONE) && ie->animated.animated)
|
||||
{
|
||||
evas_cache2_image_close(ie);
|
||||
goto use_local_cache;
|
||||
}
|
||||
}
|
||||
return ie;
|
||||
}
|
||||
use_local_cache:
|
||||
#endif
|
||||
|
||||
return evas_common_load_image_from_mmap(f, key, lo, error);
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1024,7 @@ static void
|
|||
eng_image_free(void *data EINA_UNUSED, void *image)
|
||||
{
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(image))
|
||||
{
|
||||
evas_cache2_image_close(image);
|
||||
return;
|
||||
|
@ -1031,7 +1049,7 @@ eng_image_size_set(void *data EINA_UNUSED, void *image, int w, int h)
|
|||
Image_Entry *im = image;
|
||||
if (!im) return NULL;
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(im))
|
||||
return evas_cache2_image_size_set(im, w, h);
|
||||
#endif
|
||||
return evas_cache_image_size_set(im, w, h);
|
||||
|
@ -1043,7 +1061,7 @@ eng_image_dirty_region(void *data EINA_UNUSED, void *image, int x, int y, int w,
|
|||
Image_Entry *im = image;
|
||||
if (!im) return NULL;
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(im))
|
||||
return evas_cache2_image_dirty(im, x, y, w, h);
|
||||
#endif
|
||||
return evas_cache_image_dirty(im, x, y, w, h);
|
||||
|
@ -1063,7 +1081,7 @@ eng_image_data_get(void *data EINA_UNUSED, void *image, int to_write, DATA32 **i
|
|||
im = image;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||
{
|
||||
error = evas_cache2_image_load_data(&im->cache_entry);
|
||||
if (err) *err = error;
|
||||
|
@ -1157,7 +1175,7 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *ta
|
|||
if (!im) return;
|
||||
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||
{
|
||||
evas_cache2_image_preload_data(&im->cache_entry, target);
|
||||
return;
|
||||
|
@ -1171,7 +1189,7 @@ eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *tar
|
|||
{
|
||||
RGBA_Image *im = image;
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
@ -1295,7 +1313,7 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image
|
|||
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||
{
|
||||
#if EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
|
||||
evas_cache2_image_load_data(&im->cache_entry);
|
||||
else
|
||||
#endif
|
||||
|
@ -1334,52 +1352,14 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image
|
|||
#endif
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
evas_cache2_image_load_data(&im->cache_entry);
|
||||
goto image_loaded;
|
||||
}
|
||||
#endif
|
||||
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||
evas_cache_image_load_data(&im->cache_entry);
|
||||
evas_common_image_colorspace_normalize(im);
|
||||
|
||||
image_loaded:
|
||||
#endif
|
||||
#ifdef EVAS_CSERVE2
|
||||
if (evas_cserve2_use_get())
|
||||
{
|
||||
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
|
||||
evas_cache2_image_load_data(&im->cache_entry);
|
||||
|
||||
if (!im->cache_entry.flags.loaded) return EINA_FALSE;
|
||||
evas_common_image_colorspace_normalize(im);
|
||||
|
||||
if (smooth)
|
||||
evas_common_scale_rgba_in_to_out_clip_smooth
|
||||
(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
else
|
||||
evas_common_scale_rgba_in_to_out_clip_sample
|
||||
(im, surface, context,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
evas_common_rgba_image_scalecache_prepare
|
||||
(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
evas_common_rgba_image_scalecache_do
|
||||
(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
}
|
||||
evas_common_rgba_image_scalecache_prepare
|
||||
(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
evas_common_rgba_image_scalecache_do
|
||||
(&im->cache_entry, surface, context, smooth,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);
|
||||
|
||||
evas_common_cpu_end_opt();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue