Evas: add partial rendering support for evasgl direct rendering

Evas_GL Direct rendering is an optimization path that renders
directly to the window if conditions are met.  Because evas gl
backend used to re-render the entire screen, evas_gl direct
rendering didin't have to concern with partial region rendering.
Now that partial rendering/swapping has been applied to evas gl-
backend, evas_gl direct rendering also had to take into account
clip regions. in order to properly apply it, some adjustments
were made to the engine functions and etc.
This commit is contained in:
Sung W. Park 2013-06-17 17:53:33 +09:00
parent 316be3e6c7
commit 8e6f0aa11c
11 changed files with 386 additions and 121 deletions

View File

@ -1,3 +1,7 @@
2013-06-17 Sung W. Park (sung_)
* Evas: add partial rendering support for Evas_GL direct rendering
2013-06-17 Cedric Bail
* Edje: Use Eo array of callbacks to reduce edje memory foot print.

1
NEWS
View File

@ -332,4 +332,5 @@ Fixes:
* Evas: improve stability of Evas_Cserve2.
* Evas: Fix gif cannot decode alpha value correctly.
* Evas: Fix bs if app call image object update add after call api like fileset.
* Evas: Fix evas_gl direct rendering to support partial redraw.

View File

@ -125,6 +125,7 @@ struct _Evas_Object_Image
Eina_Bool proxyerror : 1;
Eina_Bool proxy_src_clip : 1;
Eina_Bool written : 1;
Eina_Bool direct_render : 1;
};
/* private methods for image objects */
@ -3822,47 +3823,89 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
o->proxyrendering = EINA_FALSE;
}
// Clear out the pixel get stuff..
if (obj->layer->evas->engine.func->gl_get_pixels_set)
{
obj->layer->evas->engine.func->gl_get_pixels_set(output, NULL, NULL, NULL);
}
if (pixels)
{
Evas_Coord idw, idh, idx, idy;
int ix, iy, iw, ih;
int img_set = 0;
int direct_override = 0;
int direct_force_off = 0;
if (o->dirty_pixels)
{
if (o->pixels->func.get_pixels)
{
if (obj->layer->evas->engine.func->context_flush)
obj->layer->evas->engine.func->context_flush(output);
// Set img object for direct rendering optimization
// Check for image w/h against image geometry w/h
// Check for image color r,g,b,a = {255,255,255,255}
// Check and make sure that there are no maps.
if ( (obj->cur->geometry.w == o->cur->image.w) &&
(obj->cur->geometry.h == o->cur->image.h) &&
(obj->cur->color.r == 255) &&
(obj->cur->color.g == 255) &&
(obj->cur->color.b == 255) &&
(obj->cur->color.a == 255) &&
(!obj->map->cur.map) )
if (obj->layer->evas->engine.func->image_native_get)
{
if (obj->layer->evas->engine.func->gl_img_obj_set)
Evas_Native_Surface *ns;
ns = obj->layer->evas->engine.func->image_native_get(obj->layer->evas->engine.data.output, o->engine_data);
if ( (ns) &&
(ns->type == EVAS_NATIVE_SURFACE_OPENGL) &&
(ns->data.opengl.texture_id) &&
(!ns->data.opengl.framebuffer_id) )
{
obj->layer->evas->engine.func->gl_img_obj_set(output, eo_obj, o->cur->has_alpha);
img_set = 1;
// Check if we can do direct rendering...
if (obj->layer->evas->engine.func->gl_direct_override_get)
obj->layer->evas->engine.func->gl_direct_override_get(output, &direct_override, &direct_force_off);
if ( (((obj->cur->geometry.w == o->cur->image.w) &&
(obj->cur->geometry.h == o->cur->image.h) &&
(obj->cur->color.r == 255) &&
(obj->cur->color.g == 255) &&
(obj->cur->color.b == 255) &&
(obj->cur->color.a == 255) &&
(!obj->map->cur.map) &&
(!o->cur->has_alpha)) ||
(direct_override)) &&
(!direct_force_off) )
{
if (obj->layer->evas->engine.func->gl_get_pixels_set)
{
obj->layer->evas->engine.func->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
}
o->direct_render = EINA_TRUE;
}
else
o->direct_render = EINA_FALSE;
}
if ( (ns) &&
(ns->type == EVAS_NATIVE_SURFACE_X11))
{
if (obj->layer->evas->engine.func->context_flush)
obj->layer->evas->engine.func->context_flush(output);
}
}
o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, eo_obj);
if (!o->direct_render)
o->pixels->func.get_pixels(o->pixels->func.get_pixels_data, eo_obj);
if (o->engine_data != pixels)
pixels = o->engine_data;
pixels = o->engine_data;
o->engine_data = obj->layer->evas->engine.func->image_dirty_region
(obj->layer->evas->engine.data.output, o->engine_data,
0, 0, o->cur->image.w, o->cur->image.h);
}
o->dirty_pixels = EINA_FALSE;
}
else
{
// Check if the it's not dirty but it has direct rendering
if (o->direct_render)
{
obj->layer->evas->engine.func->gl_get_pixels_set(output, o->pixels->func.get_pixels, o->pixels->func.get_pixels_data, eo_obj);
}
}
if ((obj->map->cur.map) && (obj->map->cur.map->count > 3) && (obj->map->cur.usemap))
{
evas_object_map_update(eo_obj, x, y, imagew, imageh, uvw, uvh);
@ -4101,16 +4144,6 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v
if (dobreak_w) break;
}
}
// Unset img object
if (img_set)
{
if (obj->layer->evas->engine.func->gl_img_obj_set)
{
obj->layer->evas->engine.func->gl_img_obj_set(output, NULL, 0);
img_set = 0;
}
}
}
}

View File

@ -877,7 +877,8 @@ struct _Evas_Func
void *(*gl_proc_address_get) (void *data, const char *name);
int (*gl_native_surface_get) (void *data, void *surface, void *native_surface);
void *(*gl_api_get) (void *data);
void (*gl_img_obj_set) (void *data, void *image, int has_alpha);
void (*gl_direct_override_get) (void *data, int *override, int *force_off);
void (*gl_get_pixels_set) (void *data, void *get_pixels, void *get_pixels_data, void *obj);
int (*image_load_error_get) (void *data, void *image);
int (*font_run_end_get) (void *data, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);

View File

@ -153,21 +153,51 @@ _evgl_glReleaseShaderCompiler(void)
// Calls related to Evas GL Direct Rendering
//-------------------------------------------------------------//
// Transform from Evas Coordinat to GL Coordinate
// returns: oc[4] original image object dimension in gl coord
// returns: nc[4] tranformed (x, y, width, heigth) in gl coord
// returns: imgc[4] (oc[4]) original image object dimension in gl coord
// returns: objc[4] (nc[4]) tranformed (x, y, width, heigth) in gl coord
// returns: cc[4] cliped coordinate in original coordinate
static void
compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
compute_gl_coordinates(Evas_Object *obj, int rot, int clip_image,
int x, int y, int width, int height,
int imgc[4], int objc[4])
int clip[4],
int imgc[4], int objc[4], int cc[4])
{
Evas_Object_Protected_Data *pd = eo_data_scope_get(obj, EVAS_OBJ_CLASS);
int obj_x, obj_y, obj_w, obj_h;
int clip_x, clip_y, clip_w, clip_h;
int out_w, out_h;
// Original Coordinates
obj_x = pd->cur->geometry.x;
obj_y = pd->cur->geometry.y;
obj_w = pd->cur->geometry.w;
obj_h = pd->cur->geometry.h;
// Clip Region
clip_x = clip[0];
clip_y = clip[1];
clip_w = clip[2];
clip_h = clip[3];
// Output Window Size
out_w = pd->layer->evas->output.w;
out_h = pd->layer->evas->output.h;
if (rot == 0)
{
// oringinal image object coordinate in gl coordinate
imgc[0] = pd->cur->geometry.x;
imgc[1] = pd->layer->evas->output.h - pd->cur->geometry.y - pd->cur->geometry.h;
imgc[2] = imgc[0] + pd->cur->geometry.w;
imgc[3] = imgc[1] + pd->cur->geometry.h;
imgc[0] = obj_x;
imgc[1] = out_h - obj_y - obj_h;
imgc[2] = imgc[0] + obj_w;
imgc[3] = imgc[1] + obj_h;
// clip coordinates in gl coordinate
cc[0] = clip_x;
cc[1] = out_h - clip_y - clip_h;
cc[2] = cc[0] + clip_w;
cc[3] = cc[1] + clip_h;
// transformed (x,y,width,height) in gl coordinate
objc[0] = imgc[0] + x;
@ -178,14 +208,20 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
else if (rot == 180)
{
// oringinal image object coordinate in gl coordinate
imgc[0] = pd->layer->evas->output.w - pd->cur->geometry.x - pd->cur->geometry.w;
imgc[1] = pd->cur->geometry.y;
imgc[2] = imgc[0] + pd->cur->geometry.w;
imgc[3] = imgc[1] + pd->cur->geometry.h;
imgc[0] = out_w - obj_x - obj_w;
imgc[1] = obj_y;
imgc[2] = imgc[0] + obj_w;
imgc[3] = imgc[1] + obj_h;
// clip coordinates in gl coordinate
cc[0] = out_w - clip_x - clip_w;
cc[1] = clip_y;
cc[2] = cc[0] + clip_w;
cc[3] = cc[1] + clip_h;
// transformed (x,y,width,height) in gl coordinate
objc[0] = imgc[0] + pd->cur->geometry.w - x - width;
objc[1] = imgc[1] + pd->cur->geometry.h - y - height;
objc[0] = imgc[0] + obj_w - x - width;
objc[1] = imgc[1] + obj_h - y - height;
objc[2] = objc[0] + width;
objc[3] = objc[1] + height;
@ -193,13 +229,19 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
else if (rot == 90)
{
// oringinal image object coordinate in gl coordinate
imgc[0] = pd->cur->geometry.y;
imgc[1] = pd->cur->geometry.x;
imgc[2] = imgc[0] + pd->cur->geometry.h;
imgc[3] = imgc[1] + pd->cur->geometry.w;
imgc[0] = obj_y;
imgc[1] = obj_x;
imgc[2] = imgc[0] + obj_h;
imgc[3] = imgc[1] + obj_w;
// clip coordinates in gl coordinate
cc[0] = clip_y;
cc[1] = clip_x;
cc[2] = cc[0] + clip_h;
cc[3] = cc[1] + clip_w;
// transformed (x,y,width,height) in gl coordinate
objc[0] = imgc[0] + pd->cur->geometry.h - y - height;
objc[0] = imgc[0] + obj_h - y - height;
objc[1] = imgc[1] + x;
objc[2] = objc[0] + height;
objc[3] = objc[1] + width;
@ -207,14 +249,20 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
else if (rot == 270)
{
// oringinal image object coordinate in gl coordinate
imgc[0] = pd->layer->evas->output.h - pd->cur->geometry.y - pd->cur->geometry.h;
imgc[1] = pd->layer->evas->output.w - pd->cur->geometry.x - pd->cur->geometry.w;
imgc[2] = imgc[0] + pd->cur->geometry.h;
imgc[3] = imgc[1] + pd->cur->geometry.w;
imgc[0] = out_h - obj_y - obj_h;
imgc[1] = out_w - obj_x - obj_w;
imgc[2] = imgc[0] + obj_h;
imgc[3] = imgc[1] + obj_w;
// clip coordinates in gl coordinate
cc[0] = out_h - clip_y - clip_h;
cc[1] = out_w - clip_x - clip_w;
cc[2] = cc[0] + clip_h;
cc[3] = cc[1] + clip_w;
// transformed (x,y,width,height) in gl coordinate
objc[0] = imgc[0] + y;
objc[1] = imgc[1] + pd->cur->geometry.w - x - width;
objc[1] = imgc[1] + obj_w - x - width;
objc[2] = objc[0] + height;
objc[3] = objc[1] + width;
}
@ -224,7 +272,7 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
return;
}
if (clip)
if (clip_image)
{
// Clip against original image object
if (objc[0] < imgc[0]) objc[0] = imgc[0];
@ -245,6 +293,11 @@ compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
objc[2] = objc[2]-objc[0]; // width
objc[3] = objc[3]-objc[1]; // height
cc[2] = cc[2]-cc[0]; // width
cc[3] = cc[3]-cc[1]; // height
//DBG( "\e[1;32m Img[%d %d %d %d] Original [%d %d %d %d] Transformed[%d %d %d %d] Clip[%d %d %d %d] Clipped[%d %d %d %d] \e[m", obj_x, obj_y, obj_w, obj_h, imgc[0], imgc[1], imgc[2], imgc[3], objc[0], objc[1], objc[2], objc[3], clip[0], clip[1], clip[2], clip[3], cc[0], cc[1], cc[2], cc[3]);
}
static void
@ -255,6 +308,7 @@ _evgl_glClear(GLbitfield mask)
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
int cc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get()))
{
@ -288,16 +342,33 @@ _evgl_glClear(GLbitfield mask)
img = rsc->direct_img_obj;
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 0, 0, 0, 0, 0, oc, nc);
if ((ctx->scissor_updated) && (ctx->scissor_enabled))
{
glScissor(ctx->dr_scissor_coord[0], ctx->dr_scissor_coord[1],
ctx->dr_scissor_coord[2], ctx->dr_scissor_coord[3]);
compute_gl_coordinates(img, rot, 1,
ctx->scissor_coord[0],
ctx->scissor_coord[1],
ctx->scissor_coord[2],
ctx->scissor_coord[3],
rsc->clip, oc, nc, cc);
if (rsc->master_clip)
{
RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
glScissor(nc[0], nc[1], nc[2], nc[3]);
}
else
glScissor(nc[0], nc[1], nc[2], nc[3]);
ctx->direct_scissor = 0;
}
else
glScissor(oc[0], oc[1], oc[2], oc[3]);
{
compute_gl_coordinates(img, rot, 0, 0, 0, 0, 0, rsc->clip, oc, nc, cc);
if (rsc->master_clip)
glScissor(cc[0], cc[1], cc[2], cc[3]);
else
glScissor(oc[0], oc[1], oc[2], oc[3]);
}
glClear(mask);
}
@ -422,6 +493,7 @@ _evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum forma
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
int cc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get()))
@ -451,7 +523,7 @@ _evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum forma
img = rsc->direct_img_obj;
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 1, x, y, width, height, oc, nc);
compute_gl_coordinates(img, rot, 1, x, y, width, height, rsc->clip, oc, nc, cc);
glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
}
else
@ -473,6 +545,7 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
int cc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get()))
{
@ -504,9 +577,8 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
img = rsc->direct_img_obj;
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 1, x, y, width, height, oc, nc);
glScissor(nc[0], nc[1], nc[2], nc[3]);
compute_gl_coordinates(img, rot, 1, x, y, width, height, rsc->clip, oc, nc, cc);
// Keep a copy of the original coordinates
ctx->scissor_coord[0] = x;
@ -514,11 +586,13 @@ _evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
ctx->scissor_coord[2] = width;
ctx->scissor_coord[3] = height;
// Update direct rendering coordinates
ctx->dr_scissor_coord[0] = nc[0];
ctx->dr_scissor_coord[1] = nc[1];
ctx->dr_scissor_coord[2] = nc[2];
ctx->dr_scissor_coord[3] = nc[3];
if (rsc->master_clip)
{
RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
glScissor(nc[0], nc[1], nc[2], nc[3]);
}
else
glScissor(nc[0], nc[1], nc[2], nc[3]);
ctx->direct_scissor = 0;
@ -558,6 +632,7 @@ _evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Evas_Object *img;
int rot = 0;
int oc[4] = {0,0,0,0}, nc[4] = {0,0,0,0};
int cc[4] = {0,0,0,0};
if (!(rsc=_evgl_tls_resource_get()))
{
@ -591,18 +666,40 @@ _evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
img = rsc->direct_img_obj;
rot = evgl_engine->funcs->rotation_angle_get(rsc->current_eng);
compute_gl_coordinates(img, rot, 0, x, y, width, height, oc, nc);
if ((ctx->scissor_updated) && (ctx->scissor_enabled))
{
glScissor(ctx->dr_scissor_coord[0], ctx->dr_scissor_coord[1],
ctx->dr_scissor_coord[2], ctx->dr_scissor_coord[3]);
// Recompute the scissor coordinates
compute_gl_coordinates(img, rot, 1,
ctx->scissor_coord[0],
ctx->scissor_coord[1],
ctx->scissor_coord[2],
ctx->scissor_coord[3],
rsc->clip, oc, nc, cc);
if (rsc->master_clip)
{
RECTS_CLIP_TO_RECT(nc[0], nc[1], nc[2], nc[3], cc[0], cc[1], cc[2], cc[3]);
glScissor(nc[0], nc[1], nc[2], nc[3]);
}
else
glScissor(nc[0], nc[1], nc[2], nc[3]);
ctx->direct_scissor = 0;
// Compute the viewport coordinate
compute_gl_coordinates(img, rot, 0, x, y, width, height, rsc->clip, oc, nc, cc);
glViewport(nc[0], nc[1], nc[2], nc[3]);
}
else
glScissor(oc[0], oc[1], oc[2], oc[3]);
{
compute_gl_coordinates(img, rot, 0, x, y, width, height, rsc->clip, oc, nc, cc);
if (rsc->master_clip)
glScissor(cc[0], cc[1], cc[2], cc[3]);
else
glScissor(oc[0], oc[1], oc[2], oc[3]);
glViewport(nc[0], nc[1], nc[2], nc[3]);
glViewport(nc[0], nc[1], nc[2], nc[3]);
}
// Keep a copy of the original coordinates
ctx->viewport_coord[0] = x;
@ -2433,6 +2530,22 @@ _normal_gl_api_get(Evas_GL_API *funcs)
evgl_api_ext_get(funcs);
}
static void
_direct_scissor_off_api_get(Evas_GL_API *funcs)
{
#define ORD(f) EVAS_API_OVERRIDE(f, funcs,)
// For Direct Rendering
ORD(glClear);
ORD(glDisable);
ORD(glEnable);
ORD(glGetIntegerv);
ORD(glReadPixels);
ORD(glScissor);
ORD(glViewport);
#undef ORD
}
static void
_debug_gl_api_get(Evas_GL_API *funcs)
@ -2596,4 +2709,7 @@ _evgl_api_get(Evas_GL_API *funcs, int debug)
_debug_gl_api_get(funcs);
else
_normal_gl_api_get(funcs);
if (evgl_engine->direct_scissor_off)
_direct_scissor_off_api_get(funcs);
}

View File

@ -448,7 +448,7 @@ _surface_cap_check()
ERR("EVGL Engine not initialized!");
return 0;
}
// Check Surface Cap for MSAA
if (evgl_engine->caps.msaa_supported)
{
@ -507,7 +507,7 @@ _surface_cap_load(Eet_File *ef)
free(data);
data = NULL;
// !!!FIXME
// !!!FIXME
// Should use eet functionality instead of just reading using sscanfs...
for (i = 0; i < evgl_engine->caps.num_fbo_fmts; ++i)
{
@ -544,7 +544,7 @@ _surface_cap_save(Eet_File *ef)
if (eet_write(ef, "num_fbo_fmts", data, strlen(data) + 1, 1) < 0)
return 0;
// !!!FIXME
// !!!FIXME
// Should use eet functionality instead of just writing out using snprintfs...
for (i = 0; i < evgl_engine->caps.num_fbo_fmts; ++i)
{
@ -831,7 +831,7 @@ _surface_context_list_print()
DBG( RED "\t[Surface %d]" YELLOW " Ptr: %p" RED " Appx Mem: %d Byte", count++, s, (s->buffer_mem[0]+s->buffer_mem[1]+s->buffer_mem[2]+s->buffer_mem[3]));
DBG( GREEN "\t\t Size:" RESET " (%d, %d)", s->w, s->h);
if (s->buffer_mem[0])
if (s->buffer_mem[0])
{
DBG( GREEN "\t\t Color Format:" RESET " %s", _glenum_string_get(s->color_fmt));
DBG( GREEN "\t\t Color Buffer Appx. Mem Usage:" RESET " %d Byte", s->buffer_mem[0]);
@ -1247,10 +1247,10 @@ _evgl_not_in_pixel_get()
EVGL_Context *ctx = rsc->current_ctx;
if ((!evgl_engine->direct_force_off) &&
if ((!evgl_engine->direct_force_off) &&
(rsc->id == evgl_engine->main_tid) &&
(ctx) &&
(ctx->current_sfc) &&
(ctx) &&
(ctx->current_sfc) &&
(ctx->current_sfc->direct_fb_opt) &&
(!rsc->direct_img_obj))
return 1;
@ -1285,14 +1285,14 @@ _evgl_direct_enabled()
EVGL_Engine *
evgl_engine_init(void *eng_data, EVGL_Interface *efunc)
{
int direct_mem_opt = 0, direct_off = 0, debug_mode = 0;
int direct_mem_opt = 0, direct_off = 0, direct_soff = 0, debug_mode = 0;
char *s = NULL;
if (evgl_engine) return evgl_engine;
// Initialize Log Domain
if (_evas_gl_log_dom < 0)
_evas_gl_log_dom = eina_log_domain_register("EvasGL", EVAS_DEFAULT_LOG_COLOR);
_evas_gl_log_dom = eina_log_domain_register("EvasGL", EVAS_DEFAULT_LOG_COLOR);
if (_evas_gl_log_dom < 0)
{
EINA_LOG_ERR("Can not create a module log domain.");
@ -1333,9 +1333,9 @@ evgl_engine_init(void *eng_data, EVGL_Interface *efunc)
// Initialize Extensions
if (efunc->proc_address_get && efunc->ext_string_get)
evgl_api_ext_init(efunc->proc_address_get, efunc->ext_string_get(eng_data));
evgl_api_ext_init(efunc->proc_address_get, efunc->ext_string_get(eng_data));
else
ERR("Proc address get function not available. Extension not initialized.");
ERR("Proc address get function not available. Extension not initialized.");
DBG("GLUE Extension String: %s", efunc->ext_string_get(eng_data));
DBG("GL Extension String: %s", glGetString(GL_EXTENSIONS));
@ -1352,19 +1352,25 @@ evgl_engine_init(void *eng_data, EVGL_Interface *efunc)
s = getenv("EVAS_GL_DIRECT_MEM_OPT");
if (s) direct_mem_opt = atoi(s);
if (direct_mem_opt == 1)
evgl_engine->direct_mem_opt = 1;
evgl_engine->direct_mem_opt = 1;
// Check if Direct Rendering Override Force Off flag is on
s = getenv("EVAS_GL_DIRECT_OVERRIDE_FORCE_OFF");
if (s) direct_off = atoi(s);
if (direct_off == 1)
evgl_engine->direct_force_off = 1;
evgl_engine->direct_force_off = 1;
// Check if Direct Rendering Override Force Off flag is on
s = getenv("EVAS_GL_DIRECT_SCISSOR_OFF");
if (s) direct_soff = atoi(s);
if (direct_soff == 1)
evgl_engine->direct_scissor_off = 1;
// Check if API Debug mode is on
s = getenv("EVAS_GL_API_DEBUG");
if (s) debug_mode = atoi(s);
if (debug_mode == 1)
evgl_engine->api_debug_mode = 1;
evgl_engine->api_debug_mode = 1;
// Maint Thread ID (get tid not available in eina thread yet)
evgl_engine->main_tid = 0;
@ -1825,7 +1831,7 @@ evgl_direct_rendered()
}
void
evgl_direct_img_obj_set(Evas_Object *img, int alpha, int rot)
evgl_direct_img_obj_set(Evas_Object *img, int rot)
{
EVGL_Resource *rsc;
@ -1833,7 +1839,7 @@ evgl_direct_img_obj_set(Evas_Object *img, int alpha, int rot)
// Normally direct rendering isn't allowed if alpha is on and
// rotation is not 0. BUT, if override is on, allow it.
if ((alpha) || (rot!=0))
if (rot!=0)
{
if (evgl_engine->direct_override)
rsc->direct_img_obj = img;
@ -1862,6 +1868,29 @@ evgl_api_get()
return &gl_funcs;
}
void
evgl_direct_img_clip_set(int c, int x, int y, int w, int h)
{
EVGL_Resource *rsc;
if (!(rsc=_evgl_tls_resource_get())) return;
rsc->master_clip = c;
rsc->clip[0] = x;
rsc->clip[1] = y;
rsc->clip[2] = w;
rsc->clip[3] = h;
}
void
evgl_direct_override_get(int *override, int *force_off)
{
*override = evgl_engine->direct_override;
*force_off = evgl_engine->direct_force_off;
}
//-----------------------------------------------------//

View File

@ -32,8 +32,10 @@ extern void *evgl_proc_address_get(const char *name);
extern int evgl_native_surface_get(EVGL_Surface *sfc, Evas_Native_Surface *ns);
extern Evas_GL_API *evgl_api_get();
extern int evgl_direct_rendered();
extern void evgl_direct_img_obj_set(Evas_Object *img, int alpha, int rot);
extern void evgl_direct_img_obj_set(Evas_Object *img, int rot);
extern Evas_Object *evgl_direct_img_obj_get();
extern void evgl_direct_img_clip_set(int c, int x, int y, int w, int h);
extern void evgl_direct_override_get(int *override, int *force_off);
#endif //_EVAS_GL_CORE_H

View File

@ -18,7 +18,7 @@ extern int _evas_gl_log_dom;
#ifdef DBG
# undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_evas_gl_log_dom, __VA_ARGS__)
#define DBG(...) EINA_LOG_DOM_DBG(_evas_gl_log_dom, __VA_ARGS__)
#ifdef INF
# undef INF
#endif
@ -40,7 +40,7 @@ struct _EVGL_Interface
// Returns the native display of evas engine.
void *(*display_get)(void *data);
// Returns the Window surface that evas uses for direct rendering opt.
// Returns the Window surface that evas uses for direct rendering opt
void *(*evas_surface_get)(void *data);
void *(*native_window_create)(void *data);
int (*native_window_destroy)(void *data, void *window);
@ -129,7 +129,6 @@ struct _EVGL_Context
int scissor_enabled;
int scissor_updated;
int scissor_coord[4];
int dr_scissor_coord[4];
int direct_scissor;
int viewport_updated;
@ -142,7 +141,7 @@ typedef enum _EVGL_Color_Bit
{
COLOR_NONE = 0,
COLOR_RGB_888 = 0x1,
COLOR_RGBA_8888 = 0x3, // XXX: eh? not 0x2
COLOR_RGBA_8888 = 0x3,
} EVGL_Color_Bit;
@ -150,20 +149,20 @@ typedef enum _EVGL_Depth_Bit
{
DEPTH_NONE = 0,
DEPTH_BIT_8 = 0x1,
DEPTH_BIT_16 = 0x3, // XXX: eh? not 0x2
DEPTH_BIT_24 = 0x7, // XXX: eh? not 0x4
DEPTH_BIT_32 = 0xF, // XXX: eh? not 0x8
DEPTH_STENCIL = 0xFF, // XXX: eh? not 0x80
DEPTH_BIT_16 = 0x3,
DEPTH_BIT_24 = 0x7,
DEPTH_BIT_32 = 0xF,
DEPTH_STENCIL = 0xFF,
} EVGL_Depth_Bit;
typedef enum _EVGL_Stencil_Bit
{
STENCIL_NONE = 0,
STENCIL_BIT_1 = 0x1,
STENCIL_BIT_2 = 0x3, // XXX: eh? not 0x2
STENCIL_BIT_4 = 0x7, // XXX: eh? not 0x4
STENCIL_BIT_8 = 0xF, // XXX: eh? not 0x8
STENCIL_BIT_16 = 0x1F, // XXX: eh? not 0x10
STENCIL_BIT_2 = 0x3,
STENCIL_BIT_4 = 0x7,
STENCIL_BIT_8 = 0xF,
STENCIL_BIT_16 = 0x1F,
} EVGL_Stencil_Bit;
@ -212,6 +211,10 @@ struct _EVGL_Resource
int direct_rendered;
Evas_Object *direct_img_obj;
int get_pixels_set;
int master_clip;
int clip[4];
};
struct _EVGL_Engine
@ -236,9 +239,12 @@ struct _EVGL_Engine
int direct_mem_opt;
int api_debug_mode;
// Force Off fo Debug purposes
// Force Off for Debug purposes
int direct_force_off;
// Force Direct Scissoring off for Debug purposes
int direct_scissor_off;
// Keep track of all the current surfaces/contexts
Eina_List *surfaces;
Eina_List *contexts;

View File

@ -53,6 +53,12 @@ struct _Render_Engine
int lost_back;
int prev_age;
Eina_Bool evgl_initted : 1;
struct {
Evas_Object_Image_Pixels_Get_Cb get_pixels;
void *get_pixels_data;
Evas_Object *obj;
} func;
};
static int initted = 0;
@ -1505,7 +1511,7 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
}
}
else
eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
//xx if (!safe_native) eglWaitGL();
if (re->info->callback.post_swap)
{
@ -2803,10 +2809,30 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) &&
(n->ns.data.opengl.framebuffer_id == 0) &&
(evgl_direct_rendered()))
re->func.get_pixels)
{
DBG("Rendering Directly to the window: %p", data);
evas_object_image_pixels_dirty_set(evgl_direct_img_obj_get(), EINA_TRUE);
re->win->gl_context->dc = context;
if (re->func.get_pixels)
{
// Pass the clip info the evas_gl
evgl_direct_img_clip_set(1,
re->win->gl_context->dc->clip.x,
re->win->gl_context->dc->clip.y,
re->win->gl_context->dc->clip.w,
re->win->gl_context->dc->clip.h);
// Call pixel get function
evgl_direct_img_obj_set(re->func.obj, re->win->gl_context->rot);
re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
evgl_direct_img_obj_set(NULL, 0);
// Reset clip
evgl_direct_img_clip_set(0, 0, 0, 0, 0);
}
}
else
{
@ -3086,13 +3112,23 @@ eng_gl_api_get(void *data)
return evgl_api_get();
}
static void
eng_gl_img_obj_set(void *data EINA_UNUSED, void *image, int has_alpha)
eng_gl_direct_override_get(void *data, int *override, int *force_off)
{
EVGLINIT(data, );
evgl_direct_override_get(override, force_off);
}
static void
eng_gl_get_pixels_set(void *data, void *get_pixels, void *get_pixels_data, void *obj)
{
Render_Engine *re = (Render_Engine *)data;
EVGLINIT(data, );
evgl_direct_img_obj_set(image, has_alpha, re->win->gl_context->rot);
re->func.get_pixels = get_pixels;
re->func.get_pixels_data = get_pixels_data;
re->func.obj = (Evas_Object*)obj;
}
//--------------------------------//
@ -3405,7 +3441,8 @@ module_open(Evas_Module *em)
ORD(gl_proc_address_get);
ORD(gl_native_surface_get);
ORD(gl_api_get);
ORD(gl_img_obj_set);
ORD(gl_direct_override_get);
ORD(gl_get_pixels_set);
ORD(image_load_error_get);

View File

@ -2661,7 +2661,8 @@ static Evas_Func func =
NULL, // need software mesa for gl rendering <- gl_proc_address_get
NULL, // need software mesa for gl rendering <- gl_native_surface_get
NULL, // need software mesa for gl rendering <- gl_api_get
NULL, // need software mesa for gl rendering <- gl_img_obj_set
NULL, // need software mesa for gl rendering <- gl_direct_override
NULL, // need software mesa for gl rendering <- gl_get_pixels_set
eng_image_load_error_get,
eng_font_run_font_end_get,
eng_image_animated_get,

View File

@ -41,6 +41,12 @@ struct _Render_Engine
Eina_Bool lost_back : 1;
Eina_Bool end : 1;
Eina_Bool evgl_initted : 1;
struct {
Evas_Object_Image_Pixels_Get_Cb get_pixels;
void *get_pixels_data;
Evas_Object *obj;
} func;
};
typedef struct _Native Native;
@ -1392,14 +1398,22 @@ eng_gl_api_get(void *data)
return evgl_api_get();
}
static void
eng_gl_img_obj_set(void *data, void *image, int has_alpha)
static void
eng_gl_direct_override_get(void *data, int *override, int *force_off)
{
Render_Engine *re;
if (!(re = (Render_Engine *)data)) return;
EVGLINIT(data, );
evgl_direct_img_obj_set(image, has_alpha, re->win->gl_context->rot);
evgl_direct_override_get(override, force_off);
}
static void
eng_gl_get_pixels_set(void *data, void *get_pixels, void *get_pixels_data, void *obj)
{
Render_Engine *re = (Render_Engine *)data;
EVGLINIT(data, );
re->func.get_pixels = get_pixels;
re->func.get_pixels_data = get_pixels_data;
re->func.obj = (Evas_Object*)obj;
}
static void
@ -1905,10 +1919,30 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) &&
(n->ns.data.opengl.framebuffer_id == 0) &&
(evgl_direct_rendered()))
re->func.get_pixels)
{
DBG("Rendering Directly to the window: %p", data);
evas_object_image_pixels_dirty_set(evgl_direct_img_obj_get(), EINA_TRUE);
re->win->gl_context->dc = context;
if (re->func.get_pixels)
{
// Pass the clip info the evas_gl
evgl_direct_img_clip_set(1,
re->win->gl_context->dc->clip.x,
re->win->gl_context->dc->clip.y,
re->win->gl_context->dc->clip.w,
re->win->gl_context->dc->clip.h);
// Call pixel get function
evgl_direct_img_obj_set(re->func.obj, re->win->gl_context->rot);
re->func.get_pixels(re->func.get_pixels_data, re->func.obj);
evgl_direct_img_obj_set(NULL, 0);
// Reset clip
evgl_direct_img_clip_set(0, 0, 0, 0, 0);
}
}
else
{
@ -2523,7 +2557,8 @@ module_open(Evas_Module *em)
ORD(gl_proc_address_get);
ORD(gl_native_surface_get);
ORD(gl_api_get);
ORD(gl_img_obj_set);
ORD(gl_direct_override_get);
ORD(gl_get_pixels_set);
ORD(rectangle_draw);
ORD(line_draw);