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:
parent
316be3e6c7
commit
8e6f0aa11c
|
@ -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
1
NEWS
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------//
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue