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
|
||||
_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);
|
||||
|
||||
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_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);
|
||||
|
||||
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)
|
||||
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
|
||||
// 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 */
|
||||
obj->layer->evas->engine.func->context_color_set(output,
|
||||
context,
|
||||
|
@ -221,13 +229,14 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
|
|||
obj->cur->render_op);
|
||||
obj->layer->evas->engine.func->ector_begin(output, context,
|
||||
ector, surface,
|
||||
vd->engine_data,
|
||||
obj->cur->geometry.x + x, obj->cur->geometry.y + y,
|
||||
do_async);
|
||||
_evas_vg_render(obj, vd,
|
||||
output, context, surface,
|
||||
vd->root, NULL,
|
||||
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
|
||||
|
|
|
@ -1448,9 +1448,11 @@ struct _Evas_Func
|
|||
|
||||
Ector_Surface *(*ector_create) (void *data);
|
||||
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_renderer_draw) (void *data, void *context, void *surface, 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_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, 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, 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
|
||||
|
|
|
@ -721,6 +721,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
|||
if (!im)
|
||||
{
|
||||
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||
ERR("No image provided.");
|
||||
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 (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
ERR("Rotation failed.");
|
||||
return 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 (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
ERR("Ressource allocation failed.");
|
||||
return im;
|
||||
}
|
||||
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 (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||
ERR("Lock failed.");
|
||||
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 (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
||||
ERR("Allocation failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -840,6 +845,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
|
|||
if (!ok)
|
||||
{
|
||||
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
|
||||
ERR("Unlock failed.");
|
||||
return NULL;
|
||||
}
|
||||
*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);
|
||||
im = im2;
|
||||
}
|
||||
evas_gl_common_image_dirty(im, 0, 0, 0, 0);
|
||||
break;
|
||||
case EVAS_COLORSPACE_YCBCR422P601_PL:
|
||||
case EVAS_COLORSPACE_YCBCR422P709_PL:
|
||||
|
@ -2460,7 +2467,7 @@ _evas_render_op_to_ector_rop(Evas_Render_Op op)
|
|||
}
|
||||
|
||||
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_Engine_GL_Context *gc;
|
||||
|
@ -2526,16 +2533,43 @@ eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer
|
|||
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
|
||||
eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector,
|
||||
void *surface, int x, int y, Eina_Bool do_async EINA_UNUSED)
|
||||
eng_ector_free(void *engine_data)
|
||||
{
|
||||
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;
|
||||
Render_Engine_GL_Generic *re = data;
|
||||
Evas_GL_Ector *buffer = engine_data;
|
||||
int w, h;
|
||||
void *temp;
|
||||
|
||||
re->window_use(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;
|
||||
|
||||
temp = software_buffer;
|
||||
software_buffer = realloc(software_buffer, sizeof (unsigned int) * w * h);
|
||||
if (!software_buffer)
|
||||
if (!buffer->gl || buffer->gl->w != w || buffer->gl->h != h)
|
||||
{
|
||||
ERR("Realloc failed!!");
|
||||
software_buffer = temp;
|
||||
return;
|
||||
int err = EVAS_LOAD_ERROR_NONE;
|
||||
|
||||
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 ;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
Render_Engine_GL_Generic *re = data;
|
||||
Evas_GL_Image *im;
|
||||
Evas_GL_Ector *buffer = engine_data;
|
||||
int w, h;
|
||||
Eina_Bool mul_use;
|
||||
|
||||
|
@ -2592,12 +2641,12 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
|
|||
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)
|
||||
{
|
||||
// @hack as image_draw uses below fields to do colour multiplication.
|
||||
gl_context->dc->mul.col = ector_color_multiply(0xffffffff,gl_context->dc->col.col);
|
||||
gl_context->dc->mul.col = ector_color_multiply(0xffffffff, gl_context->dc->col.col);
|
||||
gl_context->dc->mul.use = EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
// using GL backend, you just need to turn on Evas_Map on
|
||||
// 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_free(im);
|
||||
evas_gl_common_image_draw(gl_context, buffer->gl, 0, 0, w, h, 0, 0, w, h, 0);
|
||||
|
||||
// restore gl state
|
||||
gl_context->dc->mul.use = mul_use;
|
||||
|
@ -2764,6 +2811,8 @@ module_open(Evas_Module *em)
|
|||
ORD(ector_begin);
|
||||
ORD(ector_renderer_draw);
|
||||
ORD(ector_end);
|
||||
ORD(ector_new);
|
||||
ORD(ector_free);
|
||||
|
||||
/* now advertise out own api */
|
||||
em->functions = (void *)(&func);
|
||||
|
|
|
@ -3795,7 +3795,7 @@ _draw_thread_ector_draw(void *data)
|
|||
}
|
||||
|
||||
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_Draw_Context *dc = context;
|
||||
|
@ -3919,8 +3919,19 @@ _draw_thread_ector_surface_set(void *data)
|
|||
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
|
||||
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)
|
||||
{
|
||||
|
@ -3963,7 +3974,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -4182,7 +4193,9 @@ static Evas_Func func =
|
|||
eng_ector_destroy,
|
||||
eng_ector_begin,
|
||||
eng_ector_renderer_draw,
|
||||
eng_ector_end
|
||||
eng_ector_end,
|
||||
eng_ector_new,
|
||||
eng_ector_free
|
||||
/* FUTURE software generic calls go here */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue