From 1d7a1bc0a841eacc433369524f999ab331bd0365 Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Tue, 22 Mar 2016 19:52:10 +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: Ie72bebea09141c2c27122cc2d3750dc0533d19e3 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 | 30 +++++++------ src/lib/evas/canvas/evas_object_vg.c | 2 +- .../evas/engines/gl_common/evas_gl_common.h | 4 ++ .../evas/engines/gl_common/evas_gl_context.c | 5 +-- .../evas/engines/gl_common/evas_gl_texture.c | 28 ++++++++++++ src/modules/evas/engines/gl_generic/evas_engine.c | 52 +++++++++++++++------- .../evas/engines/software_generic/evas_engine.c | 6 +-- 10 files changed, 108 insertions(+), 46 deletions(-) mode change 100644 => 100755 src/lib/ector/software/ector_software_surface.eo 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 old mode 100644 new mode 100755 index bea11cd..375e158 --- 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; + } } } @@ -32,3 +33,4 @@ class Ector.Software.Surface (Ector.Generic.Surface) Eo.Base.constructor; } } + 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 a8785f7..9a55282 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -680,6 +680,10 @@ void evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_P void evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int y2); +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); + + extern void (*glsym_glGenFramebuffers) (GLsizei a, GLuint *b); extern void (*glsym_glBindFramebuffer) (GLenum a, GLuint b); extern void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e); 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 df57edd..f3d89fa 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -1145,8 +1145,7 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc) if (gc->state.current.prog != PRG_INVALID) glUseProgram(gc->state.current.prog->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); } @@ -2971,7 +2970,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..461c36b 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,32 @@ _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); + GLERR(__FUNCTION__, __FILE__, __LINE__, ""); + } +} + +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) { @@ -951,6 +977,8 @@ void pt_unref(Evas_GL_Texture_Pool *pt) { if (!pt) return; + if (!pt->gc) return; + pt->references--; if (pt->references != 0) return; diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 22570e7..b87132c 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,36 +2478,41 @@ 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; } static void -eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector, +eng_ector_begin(void *data, 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); + + DATA32 *pixels; + int load_err; + + glim = eng_image_data_get(data, glim, EINA_TRUE, &pixels, &load_err, EINA_TRUE); + eng_image_size_get(data, glim, &w, &h); + eng_image_stride_get(data, glim, &stride); + memset(pixels, 0, stride * h); + if (use_cairo) { eo_do(ector, @@ -2516,14 +2522,28 @@ 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)); } } 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) +eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector, void *surface, 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 +2552,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