From 9d530761db06f4d2add5e3fadc0dbcc2a1789bd5 Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Thu, 14 Apr 2016 10:02:12 +0900 Subject: [PATCH] evas: enable dynamic flag for zero copy texture upload in ector / Bind to TEXTURE_EXTERNAL for images with dynamic hint and tbm This is backport from MCD TIZEN : commit ID : 8e2bc203d2cc2ea36123589f2eed70ef59b6a404, a2dc65a843e02fd0932673caa21d6d81f00c19fc Author: Dongyeon Kim Date: 2015-10-13 16:07:18, 2015-10-01 10:05:28 [Title] evas: enable dynamic flag for zero copy texture upload in ector / Bind to TEXTURE_EXTERNAL for images with dynamic hint and tbm[Problem] Animation slow [Cause] Texture uploading in Adreno is slow [Solution] Remove texture uploading by enabling dynamic hint set for images used in ector, and use GL_TEXTURE_EXTERNAL_OES target for texture bound from tbm surface [Team] Graphics Change-Id: Iac74ab2a7ccb22dd58464da655e7a126f46ed03d Signed-off-by: huiyu.eun --- src/lib/ector/software/ector_software_private.h | 1 + src/lib/ector/software/ector_software_rasterizer.c | 8 ++--- src/lib/ector/software/ector_software_surface.c | 18 +++++++--- src/lib/ector/software/ector_software_surface.eo | 29 +++++++-------- src/lib/evas/canvas/evas_object_vg.c | 2 +- .../evas/engines/gl_common/evas_gl_common.h | 3 ++ .../evas/engines/gl_common/evas_gl_context.c | 4 +-- .../evas/engines/gl_common/evas_gl_texture.c | 30 +++++++++++++++- src/modules/evas/engines/gl_generic/evas_engine.c | 42 +++++++++++++++------- .../evas/engines/software_generic/evas_engine.c | 6 ++-- 10 files changed, 100 insertions(+), 43 deletions(-) diff --git a/src/lib/ector/software/ector_software_private.h b/src/lib/ector/software/ector_software_private.h index a4d1221..fdbdb5c 100644 --- a/src/lib/ector/software/ector_software_private.h +++ b/src/lib/ector/software/ector_software_private.h @@ -52,6 +52,7 @@ typedef struct _Raster_Buffer { int width; int height; + int stride; DATA32 *buffer; } Raster_Buffer; diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c index 0cb74a0..d5d0479 100644 --- a/src/lib/ector/software/ector_software_rasterizer.c +++ b/src/lib/ector/software/ector_software_rasterizer.c @@ -23,11 +23,11 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) comp_func = ector_comp_func_solid_span_get(data->op, color); // move to the offset location - buffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx); + buffer = data->raster_buffer.buffer + ((data->raster_buffer.stride / 4) * data->offy + data->offx); while (count--) { - target = buffer + ((data->raster_buffer.width * spans->y) + spans->x); + target = buffer + ((data->raster_buffer.stride / 4) * spans->y + spans->x); comp_func(target, spans->len, color, spans->coverage); ++spans; } @@ -56,11 +56,11 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data) comp_func = ector_comp_func_span_get(data->op, data->mul_col, data->gradient->alpha); // move to the offset location - destbuffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx); + destbuffer = data->raster_buffer.buffer + ((data->raster_buffer.stride / 4) * data->offy + data->offx); while (count--) { - target = destbuffer + ((data->raster_buffer.width * spans->y) + spans->x); + target = destbuffer + ((data->raster_buffer.stride / 4) * spans->y + spans->x); length = spans->len; while (length) { diff --git a/src/lib/ector/software/ector_software_surface.c b/src/lib/ector/software/ector_software_surface.c index 0391150..27fe0ae 100644 --- a/src/lib/ector/software/ector_software_surface.c +++ b/src/lib/ector/software/ector_software_surface.c @@ -46,21 +46,29 @@ _ector_software_surface_context_get(Eo *obj EINA_UNUSED, void _ector_software_surface_surface_set(Eo *obj EINA_UNUSED, Ector_Software_Surface_Data *pd, - void *pixels, unsigned int width, unsigned int height) + void *pixels, unsigned int width, + unsigned int height, unsigned int stride) { pd->software->fill_data.raster_buffer.buffer = pixels; pd->software->fill_data.raster_buffer.width = width; pd->software->fill_data.raster_buffer.height = height; + pd->software->fill_data.raster_buffer.stride = stride; } void _ector_software_surface_surface_get(Eo *obj EINA_UNUSED, Ector_Software_Surface_Data *pd, - void **pixels, unsigned int *width, unsigned int *height) + void **pixels, unsigned int *width, + unsigned int *height, unsigned int *stride) { - *pixels = pd->software->fill_data.raster_buffer.buffer; - *width = pd->software->fill_data.raster_buffer.width; - *height = pd->software->fill_data.raster_buffer.height; + if (pixels) + *pixels = pd->software->fill_data.raster_buffer.buffer; + if (width) + *width = pd->software->fill_data.raster_buffer.width; + if (height) + *height = pd->software->fill_data.raster_buffer.height; + if (stride) + *stride = pd->software->fill_data.raster_buffer.stride; } static Eo * diff --git a/src/lib/ector/software/ector_software_surface.eo b/src/lib/ector/software/ector_software_surface.eo index bea11cd..5d68e00 100644 --- a/src/lib/ector/software/ector_software_surface.eo +++ b/src/lib/ector/software/ector_software_surface.eo @@ -5,23 +5,24 @@ class Ector.Software.Surface (Ector.Generic.Surface) methods { @property context { set { - } - get { - } - values { - ctx: Software_Rasterizer *; - } + } + get { + } + values { + ctx: Software_Rasterizer *; + } } @property surface { set { - } - get { - } - values { - pixels: void *; - width: uint; - height: uint; - } + } + get { + } + values { + pixels: void *; + width: uint; + height: uint; + stride: uint; + } } } diff --git a/src/lib/evas/canvas/evas_object_vg.c b/src/lib/evas/canvas/evas_object_vg.c index aff87f8..54e3a31 100644 --- a/src/lib/evas/canvas/evas_object_vg.c +++ b/src/lib/evas/canvas/evas_object_vg.c @@ -247,7 +247,7 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED, _evas_vg_render(obj, vd, output, context, vd->backing_store, vd->root, NULL,do_async); obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, vd->backing_store, 0, 0, 0, 0); - obj->layer->evas->engine.func->ector_end(output, context, ector, surface, do_async); + obj->layer->evas->engine.func->ector_end(output, context, ector, vd->backing_store, do_async); } obj->layer->evas->engine.func->image_draw(output, context, surface, vd->backing_store, 0, 0, diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index dc1c352..9517bf4 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -666,6 +666,9 @@ Evas_GL_Polygon *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, in Evas_GL_Polygon *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly); void evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int x, int y); +void evas_gl_common_texture_shared_specific(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt, int i); +void evas_gl_common_texture_shared_back(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt); + void evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int y2); extern void (*glsym_glGenFramebuffers) (GLsizei a, GLuint *b); diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index d57d094..266668b 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -1156,7 +1156,7 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc) else glUseProgram(gc->state.current.cur_prog); glActiveTexture(GL_TEXTURE0); - glBindTexture(gc->pipe[0].shader.tex_target, gc->pipe[0].shader.cur_tex); + evas_gl_common_texture_shared_back(gc, NULL); _evas_gl_common_viewport_set(gc,1); } @@ -3164,7 +3164,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc) } #endif glActiveTexture(GL_TEXTURE0); - glBindTexture(gc->pipe[i].shader.tex_target, gc->pipe[i].shader.cur_tex); + evas_gl_common_texture_shared_specific(gc, NULL, i); } if (gc->pipe[i].array.im) { diff --git a/src/modules/evas/engines/gl_common/evas_gl_texture.c b/src/modules/evas/engines/gl_common/evas_gl_texture.c index 9c31dda..0ecc218 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_texture.c +++ b/src/modules/evas/engines/gl_common/evas_gl_texture.c @@ -161,6 +161,31 @@ _evas_gl_texture_search_format(Eina_Bool alpha, Eina_Bool bgra, Evas_Colorspace return -1; } +void +evas_gl_common_texture_shared_specific(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt, int i) +{ + if (!pt || pt->texture != gc->pipe[i].shader.cur_tex) + { + if (gc->pipe[i].array.im) + { + if (gc->pipe[i].array.im->tex->pt->dyn.img) + gc->pipe[i].shader.tex_target = gc->pipe[i].array.im->tex->pt->dyn.target; + else + gc->pipe[i].shader.tex_target = gc->pipe[i].array.im->native.target; + } + else + gc->pipe[i].shader.tex_target = GL_TEXTURE_2D; + + glBindTexture(gc->pipe[i].shader.tex_target, gc->pipe[i].shader.cur_tex); + } +} + +void +evas_gl_common_texture_shared_back(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt) +{ + evas_gl_common_texture_shared_specific(gc, pt, 0); +} + static void _print_tex_count(void) { @@ -735,7 +760,10 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i _print_tex_count(); - pt->dyn.target = GL_TEXTURE_2D; + if (gc->shared->info.sec_tbm_surface) + pt->dyn.target = GL_TEXTURE_EXTERNAL_OES; + else + pt->dyn.target = GL_TEXTURE_2D; glGenTextures(1, &(pt->texture)); glBindTexture(pt->dyn.target, pt->texture); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 22570e7..8fe092c 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2447,15 +2447,16 @@ static void eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED) { Evas_GL_Image *glimg = surface; - RGBA_Image *img = glimg->im; Evas_Engine_GL_Context *gc; Render_Engine_GL_Generic *re = data; Eina_Array *c; Eina_Rectangle *r; + int w, h; + eng_image_size_get(data, glimg, &w, &h); //TODO handle, clips properly c = eina_array_new(1); - eina_array_push(c, eina_rectangle_new(0, 0, img->cache_entry.w, img->cache_entry.h)); + eina_array_push(c, eina_rectangle_new(0, 0, w, h)); gc = re->window_gl_context_get(re->software.ob); gc->dc = context; @@ -2477,23 +2478,22 @@ eng_ector_surface_create(void *data, void *surface, int width, int height) if (!surface) { surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888); + //Use this hint for ZERO COPY texture upload. + eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); } else { int cur_w , cur_h; glim = surface; - cur_w = glim->im->cache_entry.w; - cur_h = glim->im->cache_entry.h; + eng_image_size_get(data, glim, &cur_w, &cur_h); if (width != cur_w || height != cur_h) { eng_image_free(data, surface); surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888); + //Use this hint for ZERO COPY texture upload. + eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); } } - // clear the buffer - glim = surface; - void *pixels = evas_cache_image_pixels(&glim->im->cache_entry); - memset(pixels, 0, width * height *4); return surface; } @@ -2501,12 +2501,15 @@ 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) { - int w, h; + int w, h, stride; Evas_GL_Image *glim = surface; RGBA_Image *dst = glim->im; - w = dst->cache_entry.w; - h = dst->cache_entry.h; + void *pixels = evas_cache_image_pixels(&dst->cache_entry); + eng_image_stride_get(data, glim, &stride); + eng_image_size_get(data, glim, &w, &h); + memset(pixels, 0, stride * h); + if (use_cairo) { eo_do(ector, @@ -2516,7 +2519,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface else { eo_do(ector, - ector_software_surface_set(pixels, w, h), + ector_software_surface_set(pixels, w, h, stride), ector_surface_reference_point_set(x, y)); } } @@ -2524,6 +2527,19 @@ 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 EINA_UNUSED) { + void *pixels = NULL; + if (use_cairo) + { + eo_do(ector, + ector_cairo_software_surface_get(&pixels, NULL, NULL)); + } + else + { + eo_do(ector, + ector_software_surface_get(&pixels, NULL, NULL, NULL)); + } + eng_image_data_put(data, surface, pixels); + if (use_cairo) { eo_do(ector, @@ -2532,7 +2548,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface * else { eo_do(ector, - ector_software_surface_set(NULL, 0, 0)); + ector_software_surface_set(NULL, 0, 0, 0)); } } diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index e5c9505..3c0e5e4 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -3877,7 +3877,7 @@ _draw_thread_ector_surface_set(void *data) else { eo_do(ector_surface->ector, - ector_software_surface_set(pixels, w, h), + ector_software_surface_set(pixels, w, h, w * 4), ector_surface_reference_point_set(x, y)); } @@ -3927,7 +3927,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface else { eo_do(ector, - ector_software_surface_set(pixels, w, h), + ector_software_surface_set(pixels, w, h, w * 4), ector_surface_reference_point_set(x, y)); } } @@ -3958,7 +3958,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface * else { eo_do(ector, - ector_software_surface_set(NULL, 0, 0)); + ector_software_surface_set(NULL, 0, 0, 0)); } evas_common_cpu_end_opt(); -- 2.7.4