forked from enlightenment/efl
ector: improve uploading of GL texture for vector graphism
This rely on a faster code path to upload dynamic texture. Once we get support for gbm, we should see significant performance improvement in speed, but this first step is already a 5 times improvement (Ok, we get from really bad, to not really useful...).
This commit is contained in:
parent
beacff7959
commit
412191e5f8
|
@ -113,8 +113,13 @@ _cleanup_reference(void *data,
|
||||||
void
|
void
|
||||||
_evas_vg_eo_base_destructor(Eo *eo_obj, Evas_VG_Data *pd)
|
_evas_vg_eo_base_destructor(Eo *eo_obj, Evas_VG_Data *pd)
|
||||||
{
|
{
|
||||||
|
Evas_Object_Protected_Data *obj;
|
||||||
Evas *e = evas_object_evas_get(eo_obj);
|
Evas *e = evas_object_evas_get(eo_obj);
|
||||||
|
|
||||||
|
obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
if (pd->engine_data)
|
||||||
|
obj->layer->evas->engine.func->ector_free(pd->engine_data);
|
||||||
|
|
||||||
eo_do(e, eo_event_callback_del(EVAS_CANVAS_EVENT_RENDER_POST, _cleanup_reference, pd));
|
eo_do(e, eo_event_callback_del(EVAS_CANVAS_EVENT_RENDER_POST, _cleanup_reference, pd));
|
||||||
|
|
||||||
eo_unref(pd->root);
|
eo_unref(pd->root);
|
||||||
|
@ -179,7 +184,7 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, Evas_VG_Data *vd,
|
||||||
|
|
||||||
nd = eo_data_scope_get(n, EFL_VG_BASE_CLASS);
|
nd = eo_data_scope_get(n, EFL_VG_BASE_CLASS);
|
||||||
|
|
||||||
obj->layer->evas->engine.func->ector_renderer_draw(output, context, surface, nd->renderer, clips, do_async);
|
obj->layer->evas->engine.func->ector_renderer_draw(output, context, surface, vd->engine_data, nd->renderer, clips, do_async);
|
||||||
|
|
||||||
if (do_async)
|
if (do_async)
|
||||||
eina_array_push(&vd->cleanup, eo_ref(nd->renderer));
|
eina_array_push(&vd->cleanup, eo_ref(nd->renderer));
|
||||||
|
@ -202,6 +207,9 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
|
||||||
// to another Ector_Surface as long as that Ector_Surface is a
|
// to another Ector_Surface as long as that Ector_Surface is a
|
||||||
// child of the main Ector_Surface (necessary for Evas_Map).
|
// child of the main Ector_Surface (necessary for Evas_Map).
|
||||||
|
|
||||||
|
if (!vd->engine_data)
|
||||||
|
vd->engine_data = obj->layer->evas->engine.func->ector_new(output, context, ector, surface);
|
||||||
|
|
||||||
/* render object to surface with context, and offxet by x,y */
|
/* render object to surface with context, and offxet by x,y */
|
||||||
obj->layer->evas->engine.func->context_color_set(output,
|
obj->layer->evas->engine.func->context_color_set(output,
|
||||||
context,
|
context,
|
||||||
|
@ -221,13 +229,14 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
|
||||||
obj->cur->render_op);
|
obj->cur->render_op);
|
||||||
obj->layer->evas->engine.func->ector_begin(output, context,
|
obj->layer->evas->engine.func->ector_begin(output, context,
|
||||||
ector, surface,
|
ector, surface,
|
||||||
|
vd->engine_data,
|
||||||
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
||||||
do_async);
|
do_async);
|
||||||
_evas_vg_render(obj, vd,
|
_evas_vg_render(obj, vd,
|
||||||
output, context, surface,
|
output, context, surface,
|
||||||
vd->root, NULL,
|
vd->root, NULL,
|
||||||
do_async);
|
do_async);
|
||||||
obj->layer->evas->engine.func->ector_end(output, context, ector, surface, do_async);
|
obj->layer->evas->engine.func->ector_end(output, context, ector, surface, vd->engine_data, do_async);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1448,9 +1448,11 @@ struct _Evas_Func
|
||||||
|
|
||||||
Ector_Surface *(*ector_create) (void *data);
|
Ector_Surface *(*ector_create) (void *data);
|
||||||
void (*ector_destroy) (void *data, Ector_Surface *surface);
|
void (*ector_destroy) (void *data, Ector_Surface *surface);
|
||||||
void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, int x, int y, Eina_Bool do_async);
|
void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async);
|
||||||
void (*ector_renderer_draw) (void *data, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
|
void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
|
||||||
void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, Eina_Bool do_async);
|
void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
|
||||||
|
void* (*ector_new) (void *data, void *context, Ector_Surface *ector, void *surface);
|
||||||
|
void (*ector_free) (void *engine_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Image_Save_Func
|
struct _Evas_Image_Save_Func
|
||||||
|
|
|
@ -721,6 +721,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if (!im)
|
if (!im)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
ERR("No image provided.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,6 +735,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if (!im_new)
|
if (!im_new)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
ERR("Rotation failed.");
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
evas_gl_common_image_free(im);
|
evas_gl_common_image_free(im);
|
||||||
|
@ -779,6 +781,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if (!im->tex->pt->dyn.data)
|
if (!im->tex->pt->dyn.data)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
ERR("Ressource allocation failed.");
|
||||||
return im;
|
return im;
|
||||||
}
|
}
|
||||||
im->tex->pt->dyn.checked_out++;
|
im->tex->pt->dyn.checked_out++;
|
||||||
|
@ -821,6 +824,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
ERR("Lock failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,6 +834,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if (!im_new)
|
if (!im_new)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||||
|
ERR("Allocation failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,6 +845,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||||
|
ERR("Unlock failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
*image_data = im_new->im->image.data;
|
*image_data = im_new->im->image.data;
|
||||||
|
@ -974,6 +980,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
|
||||||
evas_gl_common_image_free(im);
|
evas_gl_common_image_free(im);
|
||||||
im = im2;
|
im = im2;
|
||||||
}
|
}
|
||||||
|
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||||
|
@ -2460,7 +2467,7 @@ _evas_render_op_to_ector_rop(Evas_Render_Op op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async EINA_UNUSED)
|
eng_ector_renderer_draw(void *data, void *context, void *surface, void *engine_data EINA_UNUSED, Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Evas_GL_Image *dst = surface;
|
Evas_GL_Image *dst = surface;
|
||||||
Evas_Engine_GL_Context *gc;
|
Evas_Engine_GL_Context *gc;
|
||||||
|
@ -2526,16 +2533,43 @@ eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer
|
||||||
eina_array_free(c);
|
eina_array_free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *software_buffer = NULL;
|
typedef struct _Evas_GL_Ector Evas_GL_Ector;
|
||||||
|
struct _Evas_GL_Ector
|
||||||
|
{
|
||||||
|
Evas_GL_Image *gl;
|
||||||
|
DATA32 *software;
|
||||||
|
|
||||||
|
Eina_Bool tofree;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void*
|
||||||
|
eng_ector_new(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector EINA_UNUSED, void *surface EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Evas_GL_Ector *r;
|
||||||
|
|
||||||
|
r = calloc(1, sizeof (Evas_GL_Ector));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector,
|
eng_ector_free(void *engine_data)
|
||||||
void *surface, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
{
|
||||||
|
Evas_GL_Ector *r = engine_data;
|
||||||
|
|
||||||
|
if (r->gl) evas_gl_common_image_free(r->gl);
|
||||||
|
if (r->tofree) free(r->software);
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eng_ector_begin(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
||||||
|
void *surface, void *engine_data,
|
||||||
|
int x, int y, Eina_Bool do_async EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Evas_Engine_GL_Context *gl_context;
|
Evas_Engine_GL_Context *gl_context;
|
||||||
Render_Engine_GL_Generic *re = data;
|
Render_Engine_GL_Generic *re = data;
|
||||||
|
Evas_GL_Ector *buffer = engine_data;
|
||||||
int w, h;
|
int w, h;
|
||||||
void *temp;
|
|
||||||
|
|
||||||
re->window_use(re->software.ob);
|
re->window_use(re->software.ob);
|
||||||
gl_context = re->window_gl_context_get(re->software.ob);
|
gl_context = re->window_gl_context_get(re->software.ob);
|
||||||
|
@ -2544,36 +2578,51 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
|
||||||
|
|
||||||
w = gl_context->w; h = gl_context->h;
|
w = gl_context->w; h = gl_context->h;
|
||||||
|
|
||||||
temp = software_buffer;
|
if (!buffer->gl || buffer->gl->w != w || buffer->gl->h != h)
|
||||||
software_buffer = realloc(software_buffer, sizeof (unsigned int) * w * h);
|
|
||||||
if (!software_buffer)
|
|
||||||
{
|
{
|
||||||
ERR("Realloc failed!!");
|
int err = EVAS_LOAD_ERROR_NONE;
|
||||||
software_buffer = temp;
|
|
||||||
|
if (buffer->gl) evas_gl_common_image_free(buffer->gl);
|
||||||
|
if (buffer->tofree) free(buffer->software);
|
||||||
|
buffer->software = NULL;
|
||||||
|
|
||||||
|
buffer->gl = evas_gl_common_image_new(gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
|
||||||
|
if (!buffer->gl)
|
||||||
|
{
|
||||||
|
ERR("Creation of an image for vector graphics [%i, %i] failed\n", w, h);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
memset(software_buffer, 0, sizeof (unsigned int) * w * h);
|
/* evas_gl_common_image_content_hint_set(buffer->gl, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); */
|
||||||
|
buffer->gl = eng_image_data_get(data, buffer->gl, 1, &buffer->software, &err, &buffer->tofree);
|
||||||
|
if (!buffer->gl && err != EVAS_LOAD_ERROR_NONE)
|
||||||
|
{
|
||||||
|
ERR("Mapping of an image for vector graphics [%i, %i] failed with %i\n", w, h, err);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(buffer->software, 0, sizeof (unsigned int) * w * h);
|
||||||
if (use_cairo)
|
if (use_cairo)
|
||||||
{
|
{
|
||||||
eo_do(ector,
|
eo_do(ector,
|
||||||
ector_cairo_software_surface_set(software_buffer, w, h),
|
ector_cairo_software_surface_set(buffer->software, w, h),
|
||||||
ector_surface_reference_point_set(x, y));
|
ector_surface_reference_point_set(x, y));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eo_do(ector,
|
eo_do(ector,
|
||||||
ector_software_surface_set(software_buffer, w, h),
|
ector_software_surface_set(buffer->software, w, h),
|
||||||
ector_surface_reference_point_set(x, y));
|
ector_surface_reference_point_set(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
||||||
void *surface EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
|
void *surface EINA_UNUSED, void *engine_data,
|
||||||
|
Eina_Bool do_async EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Evas_Engine_GL_Context *gl_context;
|
Evas_Engine_GL_Context *gl_context;
|
||||||
Render_Engine_GL_Generic *re = data;
|
Render_Engine_GL_Generic *re = data;
|
||||||
Evas_GL_Image *im;
|
Evas_GL_Ector *buffer = engine_data;
|
||||||
int w, h;
|
int w, h;
|
||||||
Eina_Bool mul_use;
|
Eina_Bool mul_use;
|
||||||
|
|
||||||
|
@ -2592,7 +2641,7 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
||||||
ector_software_surface_set(NULL, 0, 0));
|
ector_software_surface_set(NULL, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
im = evas_gl_common_image_new_from_copied_data(gl_context, w, h, software_buffer, 1, EVAS_COLORSPACE_ARGB8888);
|
eng_image_data_put(data, buffer->gl, buffer->software);
|
||||||
|
|
||||||
if (!mul_use)
|
if (!mul_use)
|
||||||
{
|
{
|
||||||
|
@ -2607,9 +2656,7 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
||||||
// Later on, we don't want that information and today when
|
// Later on, we don't want that information and today when
|
||||||
// using GL backend, you just need to turn on Evas_Map on
|
// using GL backend, you just need to turn on Evas_Map on
|
||||||
// the Evas_Object_VG.
|
// the Evas_Object_VG.
|
||||||
evas_gl_common_image_draw(gl_context, im, 0, 0, w, h, 0, 0, w, h, 0);
|
evas_gl_common_image_draw(gl_context, buffer->gl, 0, 0, w, h, 0, 0, w, h, 0);
|
||||||
|
|
||||||
evas_gl_common_image_free(im);
|
|
||||||
|
|
||||||
// restore gl state
|
// restore gl state
|
||||||
gl_context->dc->mul.use = mul_use;
|
gl_context->dc->mul.use = mul_use;
|
||||||
|
@ -2764,6 +2811,8 @@ module_open(Evas_Module *em)
|
||||||
ORD(ector_begin);
|
ORD(ector_begin);
|
||||||
ORD(ector_renderer_draw);
|
ORD(ector_renderer_draw);
|
||||||
ORD(ector_end);
|
ORD(ector_end);
|
||||||
|
ORD(ector_new);
|
||||||
|
ORD(ector_free);
|
||||||
|
|
||||||
/* now advertise out own api */
|
/* now advertise out own api */
|
||||||
em->functions = (void *)(&func);
|
em->functions = (void *)(&func);
|
||||||
|
|
|
@ -3795,7 +3795,7 @@ _draw_thread_ector_draw(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async)
|
eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, void *engine_data EINA_UNUSED, Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
RGBA_Image *dst = surface;
|
RGBA_Image *dst = surface;
|
||||||
RGBA_Draw_Context *dc = context;
|
RGBA_Draw_Context *dc = context;
|
||||||
|
@ -3919,8 +3919,19 @@ _draw_thread_ector_surface_set(void *data)
|
||||||
eina_mempool_free(_mp_command_ector_surface, ector_surface);
|
eina_mempool_free(_mp_command_ector_surface, ector_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
eng_ector_new(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector EINA_UNUSED, void *surface EINA_UNUSED)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector, void *surface, int x, int y, Eina_Bool do_async)
|
eng_ector_free(void *engine_data EINA_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector, void *surface, void *engine_data EINA_UNUSED, int x, int y, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
if (do_async)
|
if (do_async)
|
||||||
{
|
{
|
||||||
|
@ -3963,7 +3974,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector, void *surface EINA_UNUSED, Eina_Bool do_async)
|
eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector, void *surface EINA_UNUSED, void *engine_data EINA_UNUSED, Eina_Bool do_async)
|
||||||
{
|
{
|
||||||
if (do_async)
|
if (do_async)
|
||||||
{
|
{
|
||||||
|
@ -4182,7 +4193,9 @@ static Evas_Func func =
|
||||||
eng_ector_destroy,
|
eng_ector_destroy,
|
||||||
eng_ector_begin,
|
eng_ector_begin,
|
||||||
eng_ector_renderer_draw,
|
eng_ector_renderer_draw,
|
||||||
eng_ector_end
|
eng_ector_end,
|
||||||
|
eng_ector_new,
|
||||||
|
eng_ector_free
|
||||||
/* FUTURE software generic calls go here */
|
/* FUTURE software generic calls go here */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue