forked from enlightenment/efl
Evas filters: Complete basic repairs for GL engine
Now the filters should work with the GL engine, again, but with a potentially crazy performance. Indeed, the input buffer is now backed by an FBO, that needs to be glReadPixel'ed everytime it is accessed by the filters (mapped).
This commit is contained in:
parent
0d5b42e6bb
commit
13f66f8887
|
@ -17,16 +17,54 @@
|
|||
|
||||
#define MY_CLASS EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS
|
||||
|
||||
typedef struct _Ector_GL_Buffer_Map
|
||||
{
|
||||
EINA_INLIST;
|
||||
void *ptr;
|
||||
unsigned int size; // in bytes
|
||||
unsigned int x, y, w, h;
|
||||
Efl_Gfx_Colorspace cspace;
|
||||
Evas_GL_Image *im;
|
||||
Eina_Bool allocated;
|
||||
Ector_Buffer_Access_Flag mode;
|
||||
} Ector_GL_Buffer_Map;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ector_GL_Buffer_Base_Data *base;
|
||||
Evas *evas;
|
||||
Evas_GL_Image *image;
|
||||
struct {
|
||||
Eina_Inlist *maps; // Ector_GL_Buffer_Map
|
||||
} internal;
|
||||
} Evas_Ector_GL_Image_Buffer_Data;
|
||||
|
||||
#define ENFN e->engine.func
|
||||
#define ENDT e->engine.data.output
|
||||
|
||||
/* FIXME: Conversion routines don't belong here */
|
||||
static inline void
|
||||
_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < len; k++)
|
||||
{
|
||||
const uint32_t *s = src++;
|
||||
*dst++ = A_VAL(s);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_pixels_gry8_to_argb_convert(uint32_t *dst, const uint8_t *src, int len)
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < len; k++)
|
||||
{
|
||||
uint8_t s = *src++;
|
||||
*dst++ = ARGB_JOIN(s, s, s, s);
|
||||
}
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd,
|
||||
Evas *evas, void *image)
|
||||
|
@ -86,6 +124,128 @@ _evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUS
|
|||
if (image) *image = pd->image;
|
||||
}
|
||||
|
||||
EOLIAN static Ector_Buffer_Flag
|
||||
_evas_ector_gl_image_buffer_ector_generic_buffer_flags_get(Eo *obj EINA_UNUSED,
|
||||
Evas_Ector_GL_Image_Buffer_Data *pd)
|
||||
{
|
||||
Ector_Buffer_Flag flags;
|
||||
|
||||
if (!pd->image) return 0;
|
||||
|
||||
flags = ECTOR_BUFFER_FLAG_CPU_READABLE;
|
||||
if (pd->image->tex)
|
||||
{
|
||||
flags |= ECTOR_BUFFER_FLAG_DRAWABLE;
|
||||
if (pd->image->tex->pt->fb)
|
||||
flags |= ECTOR_BUFFER_FLAG_RENDERABLE;
|
||||
}
|
||||
if (pd->image->im)
|
||||
flags |= ECTOR_BUFFER_FLAG_CPU_WRITABLE;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
EOLIAN static void *
|
||||
_evas_ector_gl_image_buffer_ector_generic_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Image_Buffer_Data *pd, unsigned int *length,
|
||||
Ector_Buffer_Access_Flag mode,
|
||||
unsigned int x, unsigned int y, unsigned int w, unsigned int h,
|
||||
Efl_Gfx_Colorspace cspace, unsigned int *stride)
|
||||
{
|
||||
Evas_Public_Data *e = eo_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
|
||||
Ector_GL_Buffer_Map *map = NULL;
|
||||
Eina_Bool tofree = EINA_FALSE;
|
||||
Evas_GL_Image *im;
|
||||
uint32_t *data;
|
||||
int len, err;
|
||||
|
||||
im = ENFN->image_data_get(ENDT, pd->image,
|
||||
mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE,
|
||||
&data, &err, &tofree);
|
||||
if (!im) return NULL;
|
||||
|
||||
map = calloc(1, sizeof(*map));
|
||||
map->mode = mode;
|
||||
map->cspace = cspace;
|
||||
map->x = x;
|
||||
map->y = y;
|
||||
map->w = w;
|
||||
map->h = h;
|
||||
map->ptr = data;
|
||||
|
||||
if (tofree)
|
||||
map->im = im;
|
||||
else
|
||||
map->im = ENFN->image_ref(ENDT, im);
|
||||
|
||||
len = w * h;
|
||||
if (cspace == EFL_GFX_COLORSPACE_GRY8)
|
||||
{
|
||||
uint8_t *data8 = malloc(len);
|
||||
_pixels_argb_to_gry8_convert(data8, data, len);
|
||||
map->allocated = EINA_TRUE;
|
||||
map->ptr = data8;
|
||||
map->size = len;
|
||||
if (stride) *stride = w;
|
||||
}
|
||||
else
|
||||
{
|
||||
map->allocated = EINA_FALSE;
|
||||
map->ptr = data;
|
||||
map->size = len * 4;
|
||||
if (stride) *stride = w * 4;
|
||||
}
|
||||
|
||||
if (length) *length = map->size;
|
||||
|
||||
pd->internal.maps = eina_inlist_prepend(pd->internal.maps, EINA_INLIST_GET(map));
|
||||
return map->ptr;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_evas_ector_gl_image_buffer_ector_generic_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Image_Buffer_Data *pd,
|
||||
void *data, unsigned int length)
|
||||
{
|
||||
Evas_Public_Data *e = eo_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
|
||||
Ector_GL_Buffer_Map *map;
|
||||
if (!data) return;
|
||||
|
||||
EINA_INLIST_FOREACH(pd->internal.maps, map)
|
||||
{
|
||||
if ((map->ptr == data) && ((map->size == length) || (length == (unsigned int) -1)))
|
||||
{
|
||||
pd->internal.maps = eina_inlist_remove(pd->internal.maps, EINA_INLIST_GET(map));
|
||||
if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE)
|
||||
{
|
||||
CRI("Not implemented yet. Dropping pixel changes.");
|
||||
}
|
||||
ENFN->image_free(ENDT, map->im);
|
||||
if (map->allocated)
|
||||
free(map->ptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CRI("Tried to unmap a non-mapped region!");
|
||||
}
|
||||
|
||||
EOLIAN static uint8_t *
|
||||
_evas_ector_gl_image_buffer_ector_generic_buffer_span_get(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, int x, int y, unsigned int w,
|
||||
Efl_Gfx_Colorspace cspace, unsigned int *length)
|
||||
{
|
||||
// ector_buffer_map
|
||||
return _evas_ector_gl_image_buffer_ector_generic_buffer_map
|
||||
(obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_evas_ector_gl_image_buffer_ector_generic_buffer_span_free(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, uint8_t *data)
|
||||
{
|
||||
// ector_buffer_unmap
|
||||
return _evas_ector_gl_image_buffer_ector_generic_buffer_unmap
|
||||
(obj, pd, data, (unsigned int) -1);
|
||||
}
|
||||
|
||||
|
||||
EOLIAN static Eo_Base *
|
||||
_evas_ector_gl_image_buffer_eo_base_constructor(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd)
|
||||
{
|
||||
|
|
|
@ -8,5 +8,10 @@ class Evas.Ector.GL.Image.Buffer (Evas.Ector.GL.Buffer, Evas.Ector.Buffer)
|
|||
Eo.Base.destructor;
|
||||
Evas.Ector.Buffer.engine_image.set;
|
||||
Evas.Ector.Buffer.engine_image.get;
|
||||
Ector.Generic.Buffer.flags.get;
|
||||
Ector.Generic.Buffer.span_get;
|
||||
Ector.Generic.Buffer.span_free;
|
||||
Ector.Generic.Buffer.map;
|
||||
Ector.Generic.Buffer.unmap;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue