typedef struct _Evas_GL_Polygon Evas_GL_Polygon;
typedef struct _Evas_GL_Polygon_Point Evas_GL_Polygon_Point;
typedef struct _Evas_GL_Texture_Async_Preload Evas_GL_Texture_Async_Preload;
+typedef struct _Evas_GL_Image_Data_Map Evas_GL_Image_Data_Map;
typedef Eina_Bool (*evas_gl_make_current_cb)(void *engine_data, void *doit);
Eina_List *targets;
Evas_Image_Orient orient;
+ Eina_Inlist *maps; /* Evas_GL_Image_Data_Map */
+
unsigned char dirty : 1;
unsigned char cached : 1;
unsigned char alpha : 1;
Eina_Bool unpack_row_length;
};
+struct _Evas_GL_Image_Data_Map
+{
+ EINA_INLIST;
+ Evas_GL_Texture *tex; // one or the other
+ RGBA_Image *im; // one or the other
+ unsigned char *ptr;
+ int size, stride; // in bytes
+ int rx, ry, rw, rh; // actual map region
+ Evas_Colorspace cspace;
+ Efl_Gfx_Buffer_Access_Mode mode;
+};
+
/* GL_Common function that are used by gl_generic inherited module */
EAPI void evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc);
EAPI void evas_gl_common_image_ref(Evas_GL_Image *im);
Eina_Bool _need_context_restore = EINA_FALSE;
+static Evas_Func func, pfunc;
+
void
_context_restore(void)
{
{
Render_Engine_GL_Generic *re = data;
EVGLINIT(re, NULL);
- void *func = NULL;
+ void *fun = NULL;
- if (!evgl_safe_extension_get(name, &func))
+ if (!evgl_safe_extension_get(name, &fun))
{
DBG("The extension '%s' is not safe to use with Evas GL or is not "
"supported on this platform.", name);
return NULL;
}
- if (func)
- return func;
+ if (fun)
+ return fun;
if (re->evgl_funcs && re->evgl_funcs->proc_address_get)
return re->evgl_funcs->proc_address_get(name);
}
}
-static Evas_Func func, pfunc;
+static void *
+eng_image_data_map(void *engdata EINA_UNUSED, void **image,
+ int *length, int *stride,
+ int x, int y, int w, int h,
+ Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode)
+{
+ Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
+ Evas_GL_Image_Data_Map *map = NULL;
+ Evas_GL_Image *im;
+ void *ret;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL);
+ im = *image;
+
+ if (mode & EFL_GFX_BUFFER_ACCESS_MODE_COW)
+ cow = EINA_TRUE;
+
+ if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE)
+ to_write = EINA_TRUE;
+
+ if (im->im)
+ {
+ int len = 0, strid = 0;
+
+ // Call sw generic implementation. Should work for simple cases.
+ ret = pfunc.image_data_map(NULL, (void **) &im->im, &len, &strid,
+ x, y, w, h, cspace, mode);
+ if (ret)
+ {
+ map = calloc(1, sizeof(*map));
+ map->cspace = cspace;
+ map->rx = x;
+ map->ry = y;
+ map->rw = w;
+ map->rh = h;
+ map->mode = mode;
+ map->size = len;
+ map->stride = strid;
+ map->im = im->im; // ref?
+ map->ptr = ret;
+ im->maps = eina_inlist_prepend(im->maps, EINA_INLIST_GET(map));
+ }
+ if (length) *length = len;
+ if (stride) *stride = strid;
+ return ret;
+ }
+
+ // TODO: glReadPixels from FBO if possible
+
+ return NULL;
+}
+
+static Eina_Bool
+eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, void *memory, int length)
+{
+ Evas_GL_Image_Data_Map *map;
+ Evas_GL_Image *im = image;
+ Eina_Bool found = EINA_FALSE;
+
+ if (!im || !memory)
+ return EINA_FALSE;
+
+ EINA_INLIST_FOREACH(im->maps, map)
+ {
+ if ((map->ptr == memory) && (map->size == length))
+ {
+ found = EINA_TRUE;
+ if (map->im)
+ found = pfunc.image_data_unmap(NULL, map->im, memory, length);
+ if (found)
+ {
+ if (im->im && im->tex &&
+ (map->mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE))
+ evas_gl_common_texture_update(im->tex, im->im);
+ im->maps = eina_inlist_remove(im->maps, EINA_INLIST_GET(map));
+ free(map);
+ }
+ return found;
+ }
+ }
+
+ ERR("failed to unmap region %p (%u bytes)", memory, length);
+ return EINA_FALSE;
+}
+
+static int
+eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lengths)
+{
+ Evas_GL_Image_Data_Map *map;
+ const Evas_GL_Image *im = image;
+ int k = 0;
+
+ if (!im) return -1;
+
+ if (!maps || !lengths)
+ return eina_inlist_count(im->maps);
+
+ EINA_INLIST_FOREACH(im->maps, map)
+ {
+ maps[k] = map->ptr;
+ lengths[k] = map->size;
+ k++;
+ }
+
+ return k;
+}
static int
module_open(Evas_Module *em)
return 0;
}
- /* disable map/unmap for now as it's not implemented */
- pfunc.image_data_map = NULL;
- pfunc.image_data_unmap = NULL;
- pfunc.image_data_maps_get = NULL;
-
ector_init();
ector_glsym_set(dlsym, RTLD_DEFAULT);
ORD(image_cache_set);
ORD(image_cache_get);
+ ORD(image_data_map);
+ ORD(image_data_unmap);
+ ORD(image_data_maps_get);
+
ORD(font_cache_flush);
ORD(font_cache_set);
ORD(font_cache_get);
{
Eina_Bool cow = EINA_FALSE, to_write = EINA_FALSE;
RGBA_Image_Data_Map *map;
- RGBA_Image *im = *image;
- Image_Entry *ie = &im->cache_entry;
+ RGBA_Image *im;
+ Image_Entry *ie;
int src_stride, src_offset;
void *data;
EINA_SAFETY_ON_FALSE_RETURN_VAL(image && *image, NULL);
+ im = *image;
+ ie = &im->cache_entry;
// FIXME: implement planes support (YUV, RGB565, ETC1+Alpha)
// FIXME: implement YUV support (im->cs.data)
im->maps = (RGBA_Image_Data_Map *)
eina_inlist_remove(EINA_INLIST_GET(im->maps), EINA_INLIST_GET(map));
free(map);
- break;
+ return EINA_TRUE;
}
}
- if (!found)
- ERR("failed to unmap region %p (%u bytes)", memory, length);
-
- return found;
+ ERR("failed to unmap region %p (%u bytes)", memory, length);
+ return EINA_FALSE;
}
static int
-eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lenghts)
+eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lengths)
{
RGBA_Image_Data_Map *map;
const RGBA_Image *im = image;
if (!im) return -1;
- if (!maps || !lenghts)
+ if (!maps || !lengths)
return eina_inlist_count(EINA_INLIST_GET(im->maps));
EINA_INLIST_FOREACH(EINA_INLIST_GET(im->maps), map)
{
maps[k] = map->ptr;
- lenghts[k] = map->size;
+ lengths[k] = map->size;
k++;
}