From e3420b42b7d8f3a9142aad61364e4909b1e5d9c8 Mon Sep 17 00:00:00 2001 From: Seungsoo Woo Date: Mon, 28 Nov 2011 13:38:24 +0900 Subject: [PATCH] Added Evas Direct Rendering feature Change-Id: Ie2be9b43be70926b1b09b95a2794524fbf90fa8e --- src/lib/Evas_GL.h | 5 +- src/lib/canvas/evas_object_image.c | 3 + src/lib/include/evas_private.h | 1 + src/modules/engines/gl_common/evas_gl_common.h | 1 + src/modules/engines/gl_x11/evas_engine.c | 590 ++++++++++++++++----- src/modules/engines/software_generic/evas_engine.c | 1 + 6 files changed, 474 insertions(+), 127 deletions(-) diff --git a/src/lib/Evas_GL.h b/src/lib/Evas_GL.h index cb6fb69..772612a 100644 --- a/src/lib/Evas_GL.h +++ b/src/lib/Evas_GL.h @@ -19,9 +19,10 @@ typedef void *EvasGLImage; typedef enum _Evas_GL_Color_Format { EVAS_GL_RGB_888 = 0, - EVAS_GL_RGB_8 = EVAS_GL_RGB_888, + EVAS_GL_RGB_8 = EVAS_GL_RGB_888, EVAS_GL_RGBA_8888 = 1, - EVAS_GL_RGBA_8 = EVAS_GL_RGBA_8888, + EVAS_GL_RGBA_8 = EVAS_GL_RGBA_8888, + EVAS_GL_DIRECT = (1<<31) } Evas_GL_Color_Format; typedef enum _Evas_GL_Depth_Bits diff --git a/src/lib/canvas/evas_object_image.c b/src/lib/canvas/evas_object_image.c index 0e384cf..1438c31 100755 --- a/src/lib/canvas/evas_object_image.c +++ b/src/lib/canvas/evas_object_image.c @@ -2888,6 +2888,9 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su { if (o->func.get_pixels) { + + if (obj->layer->evas->engine.func->gl_img_obj_set) + obj->layer->evas->engine.func->gl_img_obj_set(output, obj); o->func.get_pixels(o->func.get_pixels_data, obj); if (o->engine_data != pixels) pixels = o->engine_data; diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index 90498d0..0fbf24b 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -839,6 +839,7 @@ 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 (*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); diff --git a/src/modules/engines/gl_common/evas_gl_common.h b/src/modules/engines/gl_common/evas_gl_common.h index a088748..3b58c36 100644 --- a/src/modules/engines/gl_common/evas_gl_common.h +++ b/src/modules/engines/gl_common/evas_gl_common.h @@ -426,6 +426,7 @@ struct _Evas_GL_Image unsigned char cached : 1; unsigned char alpha : 1; unsigned char tex_only : 1; + unsigned char direct_fb : 1; }; struct _Evas_GL_Font_Texture diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c index 38e0c13..57eb99c 100644 --- a/src/modules/engines/gl_x11/evas_engine.c +++ b/src/modules/engines/gl_x11/evas_engine.c @@ -51,6 +51,8 @@ struct _Render_Engine_GL_Surface int depth_bits; int stencil_bits; + int direct_fb; + // Render target texture/buffers GLuint rt_tex; GLint rt_internal_fmt; @@ -60,6 +62,12 @@ struct _Render_Engine_GL_Surface GLuint rb_stencil; GLenum rb_stencil_fmt; +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + EGLSurface direct_sfc; +#else + Window direct_sfc; +#endif + Render_Engine_GL_Context *current_ctx; }; @@ -74,6 +82,10 @@ struct _Render_Engine_GL_Context GLuint context_fbo; GLuint current_fbo; + + int scissor_enabled; + int scissor_upated; + Render_Engine_GL_Surface *current_sfc; }; @@ -99,7 +111,9 @@ struct _Extension_Entry static int initted = 0; static int gl_wins = 0; -static Render_Engine_GL_Context *current_evgl_ctx; +static Render_Engine_GL_Context *current_evgl_ctx = NULL; +static Render_Engine *current_engine = NULL; +static Evas_Object *current_img_obj = NULL; static Render_Engine *current_engine; static char _gl_ext_string[1024]; @@ -2185,6 +2199,9 @@ eng_image_native_set(void *data, void *image, void *native) im->native.target = GL_TEXTURE_2D; im->native.mipmap = 0; + if (ns->data.opengl.texture_id == 0) + im->direct_fb = 1; + // FIXME: need to implement mapping sub texture regions // x, y, w, h for possible texture atlasing @@ -2596,16 +2613,21 @@ static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { Render_Engine *re; + Evas_GL_Image *img = image; re = (Render_Engine *)data; if (!image) return; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_image_draw(re->win->gl_context, image, - src_x, src_y, src_w, src_h, - dst_x, dst_y, dst_w, dst_h, - smooth); + + if (img->direct_fb==0) + { + eng_window_use(re->win); + evas_gl_common_context_target_surface_set(re->win->gl_context, surface); + re->win->gl_context->dc = context; + evas_gl_common_image_draw(re->win->gl_context, image, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h, + smooth); + } } static void @@ -2788,12 +2810,16 @@ static int _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg) { // Also initialize pixel format here as well... - switch(cfg->color_format) + switch((int)cfg->color_format) { + case (EVAS_GL_RGB_888|EVAS_GL_DIRECT): + sfc->direct_fb = 1; case EVAS_GL_RGB_888: sfc->rt_fmt = GL_RGB; sfc->rt_internal_fmt = GL_RGB; break; + case (EVAS_GL_RGBA_8888|EVAS_GL_DIRECT): + sfc->direct_fb = 1; case EVAS_GL_RGBA_8888: sfc->rt_fmt = GL_RGBA; sfc->rt_internal_fmt = GL_RGBA; @@ -2956,52 +2982,64 @@ eng_gl_surface_create(void *data, void *config, int w, int h) return NULL; } - // Create internal resource context if it hasn't been created already - if ((rsc = eina_tls_get(resource_key)) == NULL) + if (sfc->direct_fb) { - if ((rsc = _create_internal_glue_resources(re)) == NULL) + printf("Directly rendering to the Evas' window. :-\)\n"); +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + sfc->direct_sfc = re->win->egl_surface[0]; +#else + sfc->direct_sfc = re->win->win; +#endif + } + else + { + // Create internal resource context if it hasn't been created already + if ((rsc = eina_tls_get(resource_key)) == NULL) { - ERR("Error creating internal resources."); - free(sfc); - return NULL; + if ((rsc = _create_internal_glue_resources(re)) == NULL) + { + ERR("Error creating internal resources."); + free(sfc); + return NULL; + } } - } - // I'm using evas's original context to create the render target texture - // This is to prevent awkwardness in using native_surface_get() function - // If the rt texture creation is deferred till the context is created and - // make_current called, the user can't call native_surface_get() right - // after the surface is created. hence this is done here using evas' context. + // I'm using evas's original context to create the render target texture + // This is to prevent awkwardness in using native_surface_get() function + // If the rt texture creation is deferred till the context is created and + // make_current called, the user can't call native_surface_get() right + // after the surface is created. hence this is done here using evas' context. #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); #else - ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); + ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); #endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - free(sfc); - return NULL; - } + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + free(sfc); + return NULL; + } - // Create Render texture - if (!_create_rt_buffers(re, sfc)) - { - ERR("_create_rt_buffers() failed."); - free(sfc); - return NULL; - } + // Create Render texture + if (!_create_rt_buffers(re, sfc)) + { + ERR("_create_rt_buffers() failed."); + free(sfc); + return NULL; + } #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); #else - ret = glXMakeCurrent(re->info->info.display, None, NULL); + ret = glXMakeCurrent(re->info->info.display, None, NULL); #endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - free(sfc); - return NULL; + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + free(sfc); + return NULL; + } } return sfc; @@ -3020,45 +3058,53 @@ eng_gl_surface_destroy(void *data, void *surface) if (!sfc) return 0; - if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; + + if (sfc->direct_fb) + { + return 1; + } + else + { + if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, rsc->surface, rsc->context); #else - ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); + ret = glXMakeCurrent(re->info->info.display, re->win->win, rsc->context); #endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - return 0; - } + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } - // Delete FBO/RBO and Texture here - if (sfc->rt_tex) - glDeleteTextures(1, &sfc->rt_tex); + // Delete FBO/RBO and Texture here + if (sfc->rt_tex) + glDeleteTextures(1, &sfc->rt_tex); - if (sfc->rb_depth) - glDeleteRenderbuffers(1, &sfc->rb_depth); + if (sfc->rb_depth) + glDeleteRenderbuffers(1, &sfc->rb_depth); - if (sfc->rb_stencil) - glDeleteRenderbuffers(1, &sfc->rb_stencil); + if (sfc->rb_stencil) + glDeleteRenderbuffers(1, &sfc->rb_stencil); #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); #else - ret = glXMakeCurrent(re->info->info.display, None, NULL); + ret = glXMakeCurrent(re->info->info.display, None, NULL); #endif - if (!ret) - { - ERR("xxxMakeCurrent() failed!"); - free(sfc); - return 0; - } + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + free(sfc); + return 0; + } - free(sfc); - surface = NULL; + free(sfc); + surface = NULL; - return 1; + return 1; + } } static void * @@ -3233,67 +3279,110 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context) return 1; } - // Do a make current only if it's not already current -#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; - - if ((eglGetCurrentContext() != ctx->context) || - (eglGetCurrentSurface(EGL_READ) != rsc->surface) || - (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) ) + if (sfc->direct_fb) { + // Do a make current only if it's not already current +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) // Flush remainder of what's in Evas' pipeline if (re->win) eng_window_use(NULL); - // Do a make current - ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, - rsc->surface, ctx->context); - if (!ret) + if ((eglGetCurrentContext() != ctx->context)) { - ERR("xxxMakeCurrent() failed!"); - return 0; + // Flush remainder of what's in Evas' pipeline + if (re->win) eng_window_use(NULL); + + // Do a make current + ret = eglMakeCurrent(re->win->egl_disp, sfc->direct_sfc, + sfc->direct_sfc, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } } - } #else - if ((glXGetCurrentContext() != ctx->context) || - (glXGetCurrentDrawable() != re->win->win) ) - { - // Flush remainder of what's in Evas' pipeline - if (re->win) eng_window_use(NULL); - - // Do a make current - ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); - if (!ret) + if ((glXGetCurrentContext() != ctx->context)) { - ERR("xxxMakeCurrent() failed!"); - return 0; + // Flush remainder of what's in Evas' pipeline + if (re->win) eng_window_use(NULL); + + // Do a make current + ret = glXMakeCurrent(re->info->info.display, sfc->direct_sfc, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } } - } + #endif - // Create FBO if not already created - if (!ctx->initialized) + } + else { - glGenFramebuffers(1, &ctx->context_fbo); - ctx->initialized = 1; + // Do a make current only if it's not already current +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; + + if ((eglGetCurrentContext() != ctx->context) || + (eglGetCurrentSurface(EGL_READ) != rsc->surface) || + (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) ) + { + // Flush remainder of what's in Evas' pipeline + if (re->win) eng_window_use(NULL); + + // Do a make current + ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, + rsc->surface, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } + } +#else + if ((glXGetCurrentContext() != ctx->context) || + (glXGetCurrentDrawable() != re->win->win) ) + { + // Flush remainder of what's in Evas' pipeline + if (re->win) eng_window_use(NULL); + + // Do a make current + ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } + } } +#endif - // Attach FBO if it hasn't been attached or if surface changed - if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc)) - { - if (!_attach_fbo_surface(re, sfc, ctx)) + // Create FBO if not already created + if (!ctx->initialized) { - ERR("_attach_fbo_surface() failed."); - return 0; + glGenFramebuffers(1, &ctx->context_fbo); + ctx->initialized = 1; } - if (ctx->current_fbo) - // Bind to the previously bound buffer - glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo); - else - // Bind FBO - glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo); + // Attach FBO if it hasn't been attached or if surface changed + if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc)) + { + if (!_attach_fbo_surface(re, sfc, ctx)) + { + ERR("_attach_fbo_surface() failed."); + return 0; + } - sfc->fbo_attached = 1; + if (ctx->current_fbo) + // Bind to the previously bound buffer + glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo); + else + // Bind FBO + glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo); + + sfc->fbo_attached = 1; + } } // Set the current surface/context @@ -3339,13 +3428,26 @@ eng_gl_native_surface_get(void *data, void *surface, void *native_surface) sfc = (Render_Engine_GL_Surface*)surface; ns = (Evas_Native_Surface*)native_surface; - ns->type = EVAS_NATIVE_SURFACE_OPENGL; - ns->version = EVAS_NATIVE_SURFACE_VERSION; - ns->data.opengl.texture_id = sfc->rt_tex; - ns->data.opengl.x = 0; - ns->data.opengl.y = 0; - ns->data.opengl.w = sfc->w; - ns->data.opengl.h = sfc->h; + if (sfc->direct_fb) + { + ns->type = EVAS_NATIVE_SURFACE_OPENGL; + ns->version = EVAS_NATIVE_SURFACE_VERSION; + ns->data.opengl.texture_id = 0; + ns->data.opengl.x = 0; + ns->data.opengl.y = 0; + ns->data.opengl.w = sfc->w; + ns->data.opengl.h = sfc->h; + } + else + { + ns->type = EVAS_NATIVE_SURFACE_OPENGL; + ns->version = EVAS_NATIVE_SURFACE_VERSION; + ns->data.opengl.texture_id = sfc->rt_tex; + ns->data.opengl.x = 0; + ns->data.opengl.y = 0; + ns->data.opengl.w = sfc->w; + ns->data.opengl.h = sfc->h; + } return 1; } @@ -3393,6 +3495,227 @@ evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer) } static void +evgl_glClear(GLbitfield mask) +{ + Render_Engine *re = current_engine; + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + if (!re) return; + + if ((ctx) && (current_img_obj) && (ctx->current_sfc->direct_fb)) + { + // Check if it's fullscreen + if ( (current_img_obj->cur.geometry.w == current_img_obj->layer->evas->output.w) && + (current_img_obj->cur.geometry.h == current_img_obj->layer->evas->output.h) && + (current_img_obj->cur.geometry.x == 0) && + (current_img_obj->cur.geometry.h == 0)) + { + glClear(mask); + } + else + { + int x, y, w, h; + + if ((!ctx->scissor_enabled) || (!ctx->scissor_upated)) + { + + w = current_img_obj->cur.geometry.w; + h = current_img_obj->cur.geometry.h; + + x = current_img_obj->cur.geometry.x; + y = current_img_obj->layer->evas->output.h - + current_img_obj->cur.geometry.y - + current_img_obj->cur.geometry.h; + + glEnable(GL_SCISSOR_TEST); + glScissor(x,y,w,h); + } + + glClear(mask); + } + } + else + glClear(mask); +} + +static void +evgl_glEnable(GLenum cap) +{ + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + if (cap == GL_SCISSOR_TEST) + if (ctx) ctx->scissor_enabled = 1; + glEnable(cap); +} + +static void +evgl_glDisable(GLenum cap) +{ + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + if (cap == GL_SCISSOR_TEST) + if (ctx) ctx->scissor_enabled = 0; + glEnable(cap); +} + +static void +evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) +{ + int nx1, ny1, nx2, ny2; + int ox1, oy1, ox2, oy2; + int current_fb = 0; + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + // Check for FB 0 + glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤t_fb); + + if ((!current_fb) && (ctx) && (current_img_obj) && (ctx->current_sfc->direct_fb)) + { + // Check if it's fullscreen + if ( (current_img_obj->cur.geometry.w == current_img_obj->layer->evas->output.w) && + (current_img_obj->cur.geometry.h == current_img_obj->layer->evas->output.h) && + (current_img_obj->cur.geometry.x == 0) && + (current_img_obj->cur.geometry.h == 0)) + { + glReadPixels(x, y, width, height, format, type, pixels); + } + else + { + // Oringinal Dimension + ox1 = current_img_obj->cur.geometry.x; + oy1 = current_img_obj->layer->evas->output.h - + current_img_obj->cur.geometry.y - + current_img_obj->cur.geometry.h; + ox2 = ox1 + current_img_obj->cur.geometry.w; + oy2 = oy1 + current_img_obj->cur.geometry.h; + + // New dimension + nx1 = ox1 + x; + ny1 = oy1 + y; + nx2 = nx1 + width; + ny2 = ny1 + height; + + // Clip New against Original + if (nx1 < ox1) nx1 = ox1; + if (nx1 > ox2) nx1 = ox2; + + if (ny1 < oy1) ny1 = oy1; + if (ny1 > oy2) ny1 = oy2; + + if (nx2 < ox1) nx1 = ox1; + if (nx2 > ox2) nx2 = ox2; + + if (ny2 < oy1) ny1 = oy1; + if (ny2 > oy2) ny2 = oy2; + + glReadPixels(nx1, ny1, nx2-nx1, ny2-ny1, format, type, pixels); + } + } + else + glReadPixels(x, y, width, height, format, type, pixels); + +} + +static void +evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + int nx1, ny1, nx2, ny2; + int ox1, oy1, ox2, oy2; + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + if ((ctx) && (current_img_obj) && (ctx->current_sfc->direct_fb)) + { + // Check if it's fullscreen + if ( (current_img_obj->cur.geometry.w == current_img_obj->layer->evas->output.w) && + (current_img_obj->cur.geometry.h == current_img_obj->layer->evas->output.h) && + (current_img_obj->cur.geometry.x == 0) && + (current_img_obj->cur.geometry.h == 0)) + { + glScissor(x, y, width, height); + } + else + { + // Oringinal Dimension + ox1 = current_img_obj->cur.geometry.x; + oy1 = current_img_obj->layer->evas->output.h - + current_img_obj->cur.geometry.y - + current_img_obj->cur.geometry.h; + ox2 = ox1 + current_img_obj->cur.geometry.w; + oy2 = oy1 + current_img_obj->cur.geometry.h; + + // New dimension + nx1 = ox1 + x; + ny1 = oy1 + y; + nx2 = nx1 + width; + ny2 = ny1 + height; + + // Clip New against Original + if (nx1 < ox1) nx1 = ox1; + if (nx1 > ox2) nx1 = ox2; + + if (ny1 < oy1) ny1 = oy1; + if (ny1 > oy2) ny1 = oy2; + + if (nx2 < ox1) nx1 = ox1; + if (nx2 > ox2) nx2 = ox2; + + if (ny2 < oy1) ny1 = oy1; + if (ny2 > oy2) ny2 = oy2; + + glScissor(nx1, ny1, nx2-nx1, ny2-ny1); + ctx->scissor_upated = 1; + } + } + else + glScissor(x, y, width, height); +} + +static void +evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + int nx1, ny1, nx2, ny2; + int ox1, oy1, ox2, oy2; + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + if ((ctx) && (current_img_obj) && (ctx->current_sfc->direct_fb)) + { + // Check if it's fullscreen + if ( (current_img_obj->cur.geometry.w == current_img_obj->layer->evas->output.w) && + (current_img_obj->cur.geometry.h == current_img_obj->layer->evas->output.h) && + (current_img_obj->cur.geometry.x == 0) && + (current_img_obj->cur.geometry.h == 0)) + { + glViewport(x, y, width, height); + } + else + { + // Oringinal Dimension + ox1 = current_img_obj->cur.geometry.x; + oy1 = current_img_obj->layer->evas->output.h - + current_img_obj->cur.geometry.y - + current_img_obj->cur.geometry.h; + ox2 = ox1 + current_img_obj->cur.geometry.w; + oy2 = oy1 + current_img_obj->cur.geometry.h; + + // New dimension + nx1 = ox1 + x; + ny1 = oy1 + y; + nx2 = nx1 + width; + ny2 = ny1 + height; + + glEnable(GL_SCISSOR_TEST); + glScissor(ox1, oy1, ox2-ox1, oy2-oy1); + glViewport(nx1, ny1, nx2-nx1, ny2-ny1); + } + } + else + glViewport(x, y, width, height); +} + + +//----------------------------------------------// + +static void evgl_glClearDepthf(GLclampf depth) { #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) @@ -3469,7 +3792,10 @@ evgl_evasglCreateImage(int target, void* buffer, int *attrib_list) attrib_list); } else - ERR("Invalid Engine... (Can't acccess EGL Display)\n"); + { + ERR("Invalid Engine... (Can't acccess EGL Display)\n"); + return NULL; + } } static void @@ -3522,7 +3848,7 @@ eng_gl_api_get(void *data) ORD(glBufferData); ORD(glBufferSubData); ORD(glCheckFramebufferStatus); - ORD(glClear); +// ORD(glClear); ORD(glClearColor); // ORD(glClearDepthf); ORD(glClearStencil); @@ -3545,11 +3871,11 @@ eng_gl_api_get(void *data) ORD(glDepthMask); // ORD(glDepthRangef); ORD(glDetachShader); - ORD(glDisable); +// ORD(glDisable); ORD(glDisableVertexAttribArray); ORD(glDrawArrays); ORD(glDrawElements); - ORD(glEnable); +// ORD(glEnable); ORD(glEnableVertexAttribArray); ORD(glFinish); ORD(glFlush); @@ -3603,7 +3929,7 @@ eng_gl_api_get(void *data) // ORD(glReleaseShaderCompiler); ORD(glRenderbufferStorage); ORD(glSampleCoverage); - ORD(glScissor); +// ORD(glScissor); // ORD(glShaderBinary); ORD(glShaderSource); ORD(glStencilFunc); @@ -3648,7 +3974,7 @@ eng_gl_api_get(void *data) ORD(glVertexAttrib4f); ORD(glVertexAttrib4fv); ORD(glVertexAttribPointer); - ORD(glViewport); +// ORD(glViewport); #undef ORD #define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_) @@ -3708,6 +4034,13 @@ eng_gl_api_get(void *data) ORD(glBindFramebuffer); ORD(glBindRenderbuffer); + ORD(glClear); + ORD(glEnable); + ORD(glDisable); + ORD(glReadPixels); + ORD(glScissor); + ORD(glViewport); + // GLES2.0 API compat on top of desktop gl ORD(glClearDepthf); ORD(glDepthRangef); @@ -3730,6 +4063,12 @@ eng_gl_api_get(void *data) return &gl_funcs; } +static void +eng_gl_img_obj_set(void *data __UNUSED__, void *image) +{ + current_img_obj = image; +} + static int eng_image_load_error_get(void *data __UNUSED__, void *image) { @@ -3939,6 +4278,7 @@ 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(image_load_error_get); diff --git a/src/modules/engines/software_generic/evas_engine.c b/src/modules/engines/software_generic/evas_engine.c index 575e61d..cf67484 100644 --- a/src/modules/engines/software_generic/evas_engine.c +++ b/src/modules/engines/software_generic/evas_engine.c @@ -1170,6 +1170,7 @@ static Evas_Func func = NULL, // FIXME: need software mesa for gl rendering <- gl_proc_address_get NULL, // FIXME: need software mesa for gl rendering <- gl_native_surface_get NULL, // FIXME: need software mesa for gl rendering <- gl_api_get + NULL, // fixme: <- gl_img_obj_set eng_image_load_error_get, eng_font_run_font_end_get, eng_image_animated_get, -- 2.7.4