aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/gl_x11/evas_engine.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/evas/src/modules/engines/gl_x11/evas_engine.c565
1 files changed, 483 insertions, 82 deletions
diff --git a/libraries/evas/src/modules/engines/gl_x11/evas_engine.c b/libraries/evas/src/modules/engines/gl_x11/evas_engine.c
index fbbd1a2..06348b4 100644
--- a/libraries/evas/src/modules/engines/gl_x11/evas_engine.c
+++ b/libraries/evas/src/modules/engines/gl_x11/evas_engine.c
@@ -41,6 +41,17 @@ struct _Render_Engine
41 int w, h; 41 int w, h;
42 int vsync; 42 int vsync;
43 43
44 // Shader used for Evas_GL_Direct Optimization
45 GLuint df_program;
46 GLuint df_vtx_shader;
47 GLuint df_fgmt_shader;
48 GLuint df_col_attrib;
49 GLuint df_pos_attrib;
50
51 GLfloat df_clear_color[4];
52 GLfloat df_depth_value;
53
54 int df_initialized;
44}; 55};
45 56
46struct _Render_Engine_GL_Surface 57struct _Render_Engine_GL_Surface
@@ -51,6 +62,8 @@ struct _Render_Engine_GL_Surface
51 int depth_bits; 62 int depth_bits;
52 int stencil_bits; 63 int stencil_bits;
53 64
65 int direct_fb_opt;
66
54 // Render target texture/buffers 67 // Render target texture/buffers
55 GLuint rt_tex; 68 GLuint rt_tex;
56 GLint rt_internal_fmt; 69 GLint rt_internal_fmt;
@@ -60,6 +73,12 @@ struct _Render_Engine_GL_Surface
60 GLuint rb_stencil; 73 GLuint rb_stencil;
61 GLenum rb_stencil_fmt; 74 GLenum rb_stencil_fmt;
62 75
76#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
77 EGLSurface direct_sfc;
78#else
79 Window direct_sfc;
80#endif
81
63 Render_Engine_GL_Context *current_ctx; 82 Render_Engine_GL_Context *current_ctx;
64}; 83};
65 84
@@ -74,6 +93,10 @@ struct _Render_Engine_GL_Context
74 GLuint context_fbo; 93 GLuint context_fbo;
75 GLuint current_fbo; 94 GLuint current_fbo;
76 95
96
97 int scissor_enabled;
98 int scissor_upated;
99
77 Render_Engine_GL_Surface *current_sfc; 100 Render_Engine_GL_Surface *current_sfc;
78}; 101};
79 102
@@ -99,8 +122,11 @@ struct _Extension_Entry
99 122
100static int initted = 0; 123static int initted = 0;
101static int gl_wins = 0; 124static int gl_wins = 0;
102static Render_Engine_GL_Context *current_evgl_ctx; 125static int gl_direct_override = 0;
103static Render_Engine *current_engine; 126static int gl_direct_enabled = 0;
127static Render_Engine_GL_Context *current_evgl_ctx = NULL;
128static Render_Engine *current_engine = NULL;
129static Evas_Object *gl_direct_img_obj = NULL;
104 130
105static char _gl_ext_string[1024]; 131static char _gl_ext_string[1024];
106static char _evasgl_ext_string[1024]; 132static char _evasgl_ext_string[1024];
@@ -2514,11 +2540,15 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
2514 2540
2515 if (im->tex->pt->dyn.data == image_data) 2541 if (im->tex->pt->dyn.data == image_data)
2516 { 2542 {
2517 im->tex->pt->dyn.checked_out--; 2543 if (im->tex->pt->dyn.checked_out > 0)
2544 {
2545 im->tex->pt->dyn.checked_out--;
2518#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) 2546#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2519 if (im->tex->pt->dyn.checked_out == 0) 2547 if (im->tex->pt->dyn.checked_out == 0)
2520 glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img); 2548 glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img);
2521#endif 2549#endif
2550 }
2551
2522 return image; 2552 return image;
2523 } 2553 }
2524 2554
@@ -2605,13 +2635,22 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x,
2605 2635
2606 re = (Render_Engine *)data; 2636 re = (Render_Engine *)data;
2607 if (!image) return; 2637 if (!image) return;
2608 eng_window_use(re->win); 2638
2609 evas_gl_common_context_target_surface_set(re->win->gl_context, surface); 2639 if ((gl_direct_img_obj) && (gl_direct_enabled))
2610 re->win->gl_context->dc = context; 2640 {
2611 evas_gl_common_image_draw(re->win->gl_context, image, 2641 DBG("Rendering Directly to the window");
2612 src_x, src_y, src_w, src_h, 2642 evas_object_image_pixels_dirty_set(gl_direct_img_obj, EINA_TRUE);
2613 dst_x, dst_y, dst_w, dst_h, 2643 }
2614 smooth); 2644 else
2645 {
2646 eng_window_use(re->win);
2647 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
2648 re->win->gl_context->dc = context;
2649 evas_gl_common_image_draw(re->win->gl_context, image,
2650 src_x, src_y, src_w, src_h,
2651 dst_x, dst_y, dst_w, dst_h,
2652 smooth);
2653 }
2615} 2654}
2616 2655
2617static void 2656static void
@@ -2794,7 +2833,7 @@ static int
2794_set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg) 2833_set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
2795{ 2834{
2796 // Also initialize pixel format here as well... 2835 // Also initialize pixel format here as well...
2797 switch(cfg->color_format) 2836 switch((int)cfg->color_format)
2798 { 2837 {
2799 case EVAS_GL_RGB_888: 2838 case EVAS_GL_RGB_888:
2800 sfc->rt_fmt = GL_RGB; 2839 sfc->rt_fmt = GL_RGB;
@@ -2849,7 +2888,12 @@ _set_internal_config(Render_Engine_GL_Surface *sfc, Evas_GL_Config *cfg)
2849 return 0; 2888 return 0;
2850 } 2889 }
2851 2890
2852 // Do Packed Depth24_Stencil8 Later... 2891 if (cfg->options_bits)
2892 {
2893 if (cfg->options_bits & EVAS_GL_OPTIONS_DIRECT)
2894 sfc->direct_fb_opt = 1;
2895 // Add other options here...
2896 }
2853 2897
2854 return 1; 2898 return 1;
2855} 2899}
@@ -2954,6 +2998,11 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
2954 sfc->rb_depth = 0; 2998 sfc->rb_depth = 0;
2955 sfc->rb_stencil = 0; 2999 sfc->rb_stencil = 0;
2956 3000
3001 /* Allow alpha for evas gl direct rendering */
3002 // FIXME!!!: A little out of place for for now...
3003 if (!gl_direct_override)
3004 if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1;
3005
2957 // Set the internal format based on the config 3006 // Set the internal format based on the config
2958 if (!_set_internal_config(sfc, cfg)) 3007 if (!_set_internal_config(sfc, cfg))
2959 { 3008 {
@@ -2962,6 +3011,16 @@ eng_gl_surface_create(void *data, void *config, int w, int h)
2962 return NULL; 3011 return NULL;
2963 } 3012 }
2964 3013
3014 if (sfc->direct_fb_opt)
3015 {
3016 DBG("Enabling Direct rendering to the Evas' window.");
3017#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3018 sfc->direct_sfc = re->win->egl_surface[0];
3019#else
3020 sfc->direct_sfc = re->win->win;
3021#endif
3022 }
3023
2965 // Create internal resource context if it hasn't been created already 3024 // Create internal resource context if it hasn't been created already
2966 if ((rsc = eina_tls_get(resource_key)) == NULL) 3025 if ((rsc = eina_tls_get(resource_key)) == NULL)
2967 { 3026 {
@@ -3039,6 +3098,17 @@ eng_gl_surface_destroy(void *data, void *surface)
3039 return 0; 3098 return 0;
3040 } 3099 }
3041 3100
3101 // Reset the Framebuffer binding point
3102 if ((current_evgl_ctx) && (current_evgl_ctx->current_fbo == current_evgl_ctx->context_fbo))
3103 {
3104 //glBindFramebuffer(GL_FRAMEBUFFER, 0);
3105 current_evgl_ctx->current_fbo = 0;
3106 current_evgl_ctx->current_sfc = NULL;
3107 }
3108
3109 // Clear direct rendering flag
3110 gl_direct_enabled = 0;
3111
3042 // Delete FBO/RBO and Texture here 3112 // Delete FBO/RBO and Texture here
3043 if (sfc->rt_tex) 3113 if (sfc->rt_tex)
3044 glDeleteTextures(1, &sfc->rt_tex); 3114 glDeleteTextures(1, &sfc->rt_tex);
@@ -3049,6 +3119,8 @@ eng_gl_surface_destroy(void *data, void *surface)
3049 if (sfc->rb_stencil) 3119 if (sfc->rb_stencil)
3050 glDeleteRenderbuffers(1, &sfc->rb_stencil); 3120 glDeleteRenderbuffers(1, &sfc->rb_stencil);
3051 3121
3122
3123
3052#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) 3124#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3053 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 3125 ret = eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
3054#else 3126#else
@@ -3158,7 +3230,7 @@ eng_gl_context_destroy(void *data, void *context)
3158 3230
3159 if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; 3231 if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
3160 3232
3161 // 1. Do a make current with the given context 3233 // Do a make current with the given context
3162#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) 3234#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3163 ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, 3235 ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
3164 rsc->surface, ctx->context); 3236 rsc->surface, ctx->context);
@@ -3172,11 +3244,11 @@ eng_gl_context_destroy(void *data, void *context)
3172 return 0; 3244 return 0;
3173 } 3245 }
3174 3246
3175 // 2. Delete the FBO 3247 // Delete the FBO
3176 if (ctx->context_fbo) 3248 if (ctx->context_fbo)
3177 glDeleteFramebuffers(1, &ctx->context_fbo); 3249 glDeleteFramebuffers(1, &ctx->context_fbo);
3178 3250
3179 // 3. Destroy the Context 3251 // Destroy the Context
3180#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) 3252#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3181 eglDestroyContext(re->win->egl_disp, ctx->context); 3253 eglDestroyContext(re->win->egl_disp, ctx->context);
3182 3254
@@ -3239,67 +3311,127 @@ eng_gl_make_current(void *data __UNUSED__, void *surface, void *context)
3239 return 1; 3311 return 1;
3240 } 3312 }
3241 3313
3242 // Do a make current only if it's not already current 3314 // Check if direct rendering is possible:
3243#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) 3315 // It's possible when direct_fb_opt is on and either current image
3244 if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0; 3316 // object is valid or gl_direct_override is on. Override allows
3317 // rendering outside of pixel getter but it doesn't guarantee
3318 // correct rendering.
3319 if ((sfc->direct_fb_opt) && (gl_direct_img_obj || gl_direct_override))
3320 gl_direct_enabled = 1;
3321 else
3322 gl_direct_enabled = 0;
3245 3323
3246 if ((eglGetCurrentContext() != ctx->context) || 3324 if (gl_direct_enabled)
3247 (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
3248 (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) )
3249 { 3325 {
3250 // Flush remainder of what's in Evas' pipeline 3326 // Do a make current only if it's not already current
3251 if (re->win) eng_window_use(NULL); 3327#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3328 if ((eglGetCurrentContext() != ctx->context) ||
3329 (eglGetCurrentSurface(EGL_READ) != sfc->direct_sfc) ||
3330 (eglGetCurrentSurface(EGL_DRAW) != sfc->direct_sfc) )
3331 {
3332 int curr_fbo = 0;
3333 DBG("Rendering Directly to the window\n");
3252 3334
3253 // Do a make current 3335 // Flush remainder of what's in Evas' pipeline
3254 ret = eglMakeCurrent(re->win->egl_disp, rsc->surface, 3336 if (re->win) eng_window_use(NULL);
3255 rsc->surface, ctx->context); 3337
3256 if (!ret) 3338 // Do a make current
3339 ret = eglMakeCurrent(re->win->egl_disp, sfc->direct_sfc,
3340 sfc->direct_sfc, ctx->context);
3341 if (!ret)
3342 {
3343 ERR("xxxMakeCurrent() failed! code=%#x", eglGetError());
3344 //ERR("xxxMakeCurrent() failed!");
3345 return 0;
3346 }
3347
3348 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curr_fbo);
3349 if (ctx->context_fbo == curr_fbo)
3350 {
3351 ctx->current_fbo = 0;
3352 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3353 }
3354 }
3355#else
3356 if ((glXGetCurrentContext() != ctx->context))
3257 { 3357 {
3258 ERR("xxxMakeCurrent() failed!"); 3358 // Flush remainder of what's in Evas' pipeline
3259 return 0; 3359 if (re->win) eng_window_use(NULL);
3360
3361 // Do a make current
3362 ret = glXMakeCurrent(re->info->info.display, sfc->direct_sfc, ctx->context);
3363 if (!ret)
3364 {
3365 ERR("xxxMakeCurrent() failed!");
3366 return 0;
3367 }
3260 } 3368 }
3369#endif
3261 } 3370 }
3262#else 3371 else
3263 if ((glXGetCurrentContext() != ctx->context) ||
3264 (glXGetCurrentDrawable() != re->win->win) )
3265 { 3372 {
3266 // Flush remainder of what's in Evas' pipeline 3373 // Do a make current only if it's not already current
3267 if (re->win) eng_window_use(NULL); 3374#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
3375 if ((rsc = eina_tls_get(resource_key)) == EINA_FALSE) return 0;
3268 3376
3269 // Do a make current 3377 if ((eglGetCurrentContext() != ctx->context) ||
3270 ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); 3378 (eglGetCurrentSurface(EGL_READ) != rsc->surface) ||
3271 if (!ret) 3379 (eglGetCurrentSurface(EGL_DRAW) != rsc->surface) )
3272 { 3380 {
3273 ERR("xxxMakeCurrent() failed!"); 3381 // Flush remainder of what's in Evas' pipeline
3274 return 0; 3382 if (re->win) eng_window_use(NULL);
3383
3384 // Do a make current
3385 ret = eglMakeCurrent(re->win->egl_disp, rsc->surface,
3386 rsc->surface, ctx->context);
3387 if (!ret)
3388 {
3389 ERR("xxxMakeCurrent() failed!");
3390 return 0;
3391 }
3275 } 3392 }
3276 } 3393#else
3277#endif 3394 if ((glXGetCurrentContext() != ctx->context) ||
3395 (glXGetCurrentDrawable() != re->win->win) )
3396 {
3397 // Flush remainder of what's in Evas' pipeline
3398 if (re->win) eng_window_use(NULL);
3278 3399
3279 // Create FBO if not already created 3400 // Do a make current
3280 if (!ctx->initialized) 3401 ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context);
3281 { 3402 if (!ret)
3282 glGenFramebuffers(1, &ctx->context_fbo); 3403 {
3283 ctx->initialized = 1; 3404 ERR("xxxMakeCurrent() failed!");
3284 } 3405 return 0;
3406 }
3407 }
3408#endif
3285 3409
3286 // Attach FBO if it hasn't been attached or if surface changed 3410 // Create FBO if not already created
3287 if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc)) 3411 if (!ctx->initialized)
3288 {
3289 if (!_attach_fbo_surface(re, sfc, ctx))
3290 { 3412 {
3291 ERR("_attach_fbo_surface() failed."); 3413 glGenFramebuffers(1, &ctx->context_fbo);
3292 return 0; 3414 ctx->initialized = 1;
3293 } 3415 }
3294 3416
3295 if (ctx->current_fbo) 3417 // Attach FBO if it hasn't been attached or if surface changed
3296 // Bind to the previously bound buffer 3418 if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc))
3297 glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo); 3419 {
3298 else 3420 if (!_attach_fbo_surface(re, sfc, ctx))
3299 // Bind FBO 3421 {
3300 glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo); 3422 ERR("_attach_fbo_surface() failed.");
3423 return 0;
3424 }
3301 3425
3302 sfc->fbo_attached = 1; 3426 if (ctx->current_fbo)
3427 // Bind to the previously bound buffer
3428 glBindFramebuffer(GL_FRAMEBUFFER, ctx->current_fbo);
3429 else
3430 // Bind FBO
3431 glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo);
3432
3433 sfc->fbo_attached = 1;
3434 }
3303 } 3435 }
3304 3436
3305 // Set the current surface/context 3437 // Set the current surface/context
@@ -3345,13 +3477,28 @@ eng_gl_native_surface_get(void *data, void *surface, void *native_surface)
3345 sfc = (Render_Engine_GL_Surface*)surface; 3477 sfc = (Render_Engine_GL_Surface*)surface;
3346 ns = (Evas_Native_Surface*)native_surface; 3478 ns = (Evas_Native_Surface*)native_surface;
3347 3479
3348 ns->type = EVAS_NATIVE_SURFACE_OPENGL; 3480 if (sfc->direct_fb_opt)
3349 ns->version = EVAS_NATIVE_SURFACE_VERSION; 3481 {
3350 ns->data.opengl.texture_id = sfc->rt_tex; 3482 ns->type = EVAS_NATIVE_SURFACE_OPENGL;
3351 ns->data.opengl.x = 0; 3483 ns->version = EVAS_NATIVE_SURFACE_VERSION;
3352 ns->data.opengl.y = 0; 3484 ns->data.opengl.texture_id = sfc->rt_tex;
3353 ns->data.opengl.w = sfc->w; 3485 ns->data.opengl.framebuffer_id = 0;
3354 ns->data.opengl.h = sfc->h; 3486 ns->data.opengl.x = 0;
3487 ns->data.opengl.y = 0;
3488 ns->data.opengl.w = sfc->w;
3489 ns->data.opengl.h = sfc->h;
3490 }
3491 else
3492 {
3493 ns->type = EVAS_NATIVE_SURFACE_OPENGL;
3494 ns->version = EVAS_NATIVE_SURFACE_VERSION;
3495 ns->data.opengl.texture_id = sfc->rt_tex;
3496 ns->data.opengl.framebuffer_id = sfc->rt_tex;
3497 ns->data.opengl.x = 0;
3498 ns->data.opengl.y = 0;
3499 ns->data.opengl.w = sfc->w;
3500 ns->data.opengl.h = sfc->h;
3501 }
3355 3502
3356 return 1; 3503 return 1;
3357} 3504}
@@ -3371,22 +3518,27 @@ evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
3371{ 3518{
3372 Render_Engine_GL_Context *ctx = current_evgl_ctx; 3519 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3373 3520
3521 if (!ctx)
3522 {
3523 ERR("No current context set.");
3524 return;
3525 }
3526
3374 // Take care of BindFramebuffer 0 issue 3527 // Take care of BindFramebuffer 0 issue
3375 if (framebuffer==0) 3528 if (framebuffer==0)
3376 { 3529 {
3377 if (ctx) 3530 if (gl_direct_enabled)
3378 { 3531 glBindFramebuffer(target, 0);
3379 glBindFramebuffer(target, ctx->context_fbo); 3532 else
3380 ctx->current_fbo = 0; 3533 glBindFramebuffer(target, ctx->context_fbo);
3381 } 3534 ctx->current_fbo = 0;
3382 } 3535 }
3383 else 3536 else
3384 { 3537 {
3385 glBindFramebuffer(target, framebuffer); 3538 glBindFramebuffer(target, framebuffer);
3386 3539
3387 // Save this for restore when doing make current 3540 // Save this for restore when doing make current
3388 if (ctx) 3541 ctx->current_fbo = framebuffer;
3389 ctx->current_fbo = framebuffer;
3390 } 3542 }
3391} 3543}
3392 3544
@@ -3398,6 +3550,225 @@ evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
3398 glBindRenderbuffer(target, renderbuffer); 3550 glBindRenderbuffer(target, renderbuffer);
3399} 3551}
3400 3552
3553// Transform from Evas Coordinat to GL Coordinate
3554// returns: oc[4] original image object dimension in gl coord
3555// returns: nc[4] tranformed (x, y, width, heigth) in gl coord
3556static void
3557compute_gl_coordinates(Evas_Object *obj, int rot, int clip,
3558 int x, int y, int width, int height,
3559 int imgc[4], int objc[4])
3560{
3561 if (rot == 0)
3562 {
3563 // oringinal image object coordinate in gl coordinate
3564 imgc[0] = obj->cur.geometry.x;
3565 imgc[1] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
3566 imgc[2] = imgc[0] + obj->cur.geometry.w;
3567 imgc[3] = imgc[1] + obj->cur.geometry.h;
3568
3569 // transformed (x,y,width,height) in gl coordinate
3570 objc[0] = imgc[0] + x;
3571 objc[1] = imgc[1] + y;
3572 objc[2] = objc[0] + width;
3573 objc[3] = objc[1] + height;
3574 }
3575 else if (rot == 180)
3576 {
3577 // oringinal image object coordinate in gl coordinate
3578 imgc[0] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w;
3579 imgc[1] = obj->cur.geometry.y;
3580 imgc[2] = imgc[0] + obj->cur.geometry.w;
3581 imgc[3] = imgc[1] + obj->cur.geometry.h;
3582
3583 // transformed (x,y,width,height) in gl coordinate
3584 objc[0] = imgc[0] + obj->cur.geometry.w - x - width;
3585 objc[1] = imgc[1] + obj->cur.geometry.h - y - height;
3586 objc[2] = objc[0] + width;
3587 objc[3] = objc[1] + height;
3588
3589 }
3590 else if (rot == 90)
3591 {
3592 // oringinal image object coordinate in gl coordinate
3593 imgc[0] = obj->cur.geometry.y;
3594 imgc[1] = obj->cur.geometry.x;
3595 imgc[2] = imgc[0] + obj->cur.geometry.h;
3596 imgc[3] = imgc[1] + obj->cur.geometry.w;
3597
3598 // transformed (x,y,width,height) in gl coordinate
3599 objc[0] = imgc[0] + obj->cur.geometry.h - y - height;
3600 objc[1] = imgc[1] + x;
3601 objc[2] = objc[0] + height;
3602 objc[3] = objc[1] + width;
3603 }
3604 else if (rot == 270)
3605 {
3606 // oringinal image object coordinate in gl coordinate
3607 imgc[0] = obj->layer->evas->output.h - obj->cur.geometry.y - obj->cur.geometry.h;
3608 imgc[1] = obj->layer->evas->output.w - obj->cur.geometry.x - obj->cur.geometry.w;
3609 imgc[2] = imgc[0] + obj->cur.geometry.h;
3610 imgc[3] = imgc[1] + obj->cur.geometry.w;
3611
3612 // transformed (x,y,width,height) in gl coordinate
3613 objc[0] = imgc[0] + y;
3614 objc[1] = imgc[1] + obj->cur.geometry.w - x - width;
3615 objc[2] = objc[0] + height;
3616 objc[3] = objc[1] + width;
3617 }
3618 else
3619 {
3620 ERR("Invalid rotation angle %d.", rot);
3621 return;
3622 }
3623
3624 if (clip)
3625 {
3626 // Clip against original image object
3627 if (objc[0] < imgc[0]) objc[0] = imgc[0];
3628 if (objc[0] > imgc[2]) objc[0] = 0;
3629
3630 if (objc[1] < imgc[1]) objc[1] = imgc[1];
3631 if (objc[1] > imgc[3]) objc[1] = 0;
3632
3633 if (objc[2] < imgc[0]) objc[0] = 0;
3634 if (objc[2] > imgc[2]) objc[2] = imgc[2];
3635
3636 if (objc[3] < imgc[1]) objc[1] = 0;
3637 if (objc[3] > imgc[3]) objc[3] = imgc[3];
3638 }
3639
3640 imgc[2] = imgc[2]-imgc[0]; // width
3641 imgc[3] = imgc[3]-imgc[1]; // height
3642
3643 objc[2] = objc[2]-objc[0]; // width
3644 objc[3] = objc[3]-objc[1]; // height
3645}
3646
3647static void
3648evgl_glClear(GLbitfield mask)
3649{
3650 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3651 int rot = 0;
3652 int oc[4], nc[4];
3653
3654 if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
3655 {
3656 if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
3657 rot = current_engine->win->gl_context->rot;
3658 else
3659 ERR("Unable to retrieve rotation angle: %d", rot);
3660
3661 compute_gl_coordinates(gl_direct_img_obj, rot, 0, 0, 0, 0, 0, oc, nc);
3662 glScissor(oc[0], oc[1], oc[2], oc[3]);
3663 glClear(mask);
3664 }
3665 else
3666 glClear(mask);
3667}
3668
3669static void
3670evgl_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3671{
3672 current_engine->df_clear_color[0] = red;
3673 current_engine->df_clear_color[1] = green;
3674 current_engine->df_clear_color[2] = blue;
3675 current_engine->df_clear_color[3] = alpha;
3676
3677 glClearColor(red, green, blue, alpha);
3678
3679}
3680
3681static void
3682evgl_glEnable(GLenum cap)
3683{
3684 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3685
3686 if (cap == GL_SCISSOR_TEST)
3687 if (ctx) ctx->scissor_enabled = 1;
3688 glEnable(cap);
3689}
3690
3691static void
3692evgl_glDisable(GLenum cap)
3693{
3694 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3695
3696 if (cap == GL_SCISSOR_TEST)
3697 if (ctx) ctx->scissor_enabled = 0;
3698 glDisable(cap);
3699}
3700
3701
3702static void
3703evgl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
3704{
3705 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3706 int rot = 0;
3707 int oc[4], nc[4];
3708
3709 if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
3710 {
3711 if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
3712 rot = current_engine->win->gl_context->rot;
3713 else
3714 ERR("Unable to retrieve rotation angle: %d", rot);
3715
3716 compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc);
3717 glReadPixels(nc[0], nc[1], nc[2], nc[3], format, type, pixels);
3718 }
3719 else
3720 glReadPixels(x, y, width, height, format, type, pixels);
3721}
3722
3723static void
3724evgl_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3725{
3726 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3727 int rot = 0;
3728 int oc[4], nc[4];
3729
3730 if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
3731 {
3732 if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
3733 rot = current_engine->win->gl_context->rot;
3734 else
3735 ERR("Unable to retrieve rotation angle: %d", rot);
3736
3737 compute_gl_coordinates(gl_direct_img_obj, rot, 1, x, y, width, height, oc, nc);
3738 glScissor(nc[0], nc[1], nc[2], nc[3]);
3739 ctx->scissor_upated = 1;
3740 }
3741 else
3742 glScissor(x, y, width, height);
3743}
3744
3745static void
3746evgl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
3747{
3748 Render_Engine_GL_Context *ctx = current_evgl_ctx;
3749 int rot = 0;
3750 int oc[4], nc[4];
3751
3752 if ((gl_direct_img_obj) && (gl_direct_enabled) && (ctx) && (!ctx->current_fbo))
3753 {
3754 if ((current_engine) && (current_engine->win) && (current_engine->win->gl_context))
3755 rot = current_engine->win->gl_context->rot;
3756 else
3757 ERR("Unable to retrieve rotation angle: %d", rot);
3758
3759 compute_gl_coordinates(gl_direct_img_obj, rot, 0, x, y, width, height, oc, nc);
3760 glEnable(GL_SCISSOR_TEST);
3761 glScissor(oc[0], oc[1], oc[2], oc[3]);
3762 glViewport(nc[0], nc[1], nc[2], nc[3]);
3763 }
3764 else
3765 glViewport(x, y, width, height);
3766
3767}
3768
3769
3770//----------------------------------------------//
3771
3401static void 3772static void
3402evgl_glClearDepthf(GLclampf depth) 3773evgl_glClearDepthf(GLclampf depth)
3403{ 3774{
@@ -3531,8 +3902,8 @@ eng_gl_api_get(void *data)
3531 ORD(glBufferData); 3902 ORD(glBufferData);
3532 ORD(glBufferSubData); 3903 ORD(glBufferSubData);
3533 ORD(glCheckFramebufferStatus); 3904 ORD(glCheckFramebufferStatus);
3534 ORD(glClear); 3905// ORD(glClear);
3535 ORD(glClearColor); 3906// ORD(glClearColor);
3536// ORD(glClearDepthf); 3907// ORD(glClearDepthf);
3537 ORD(glClearStencil); 3908 ORD(glClearStencil);
3538 ORD(glColorMask); 3909 ORD(glColorMask);
@@ -3554,11 +3925,11 @@ eng_gl_api_get(void *data)
3554 ORD(glDepthMask); 3925 ORD(glDepthMask);
3555// ORD(glDepthRangef); 3926// ORD(glDepthRangef);
3556 ORD(glDetachShader); 3927 ORD(glDetachShader);
3557 ORD(glDisable); 3928// ORD(glDisable);
3558 ORD(glDisableVertexAttribArray); 3929 ORD(glDisableVertexAttribArray);
3559 ORD(glDrawArrays); 3930 ORD(glDrawArrays);
3560 ORD(glDrawElements); 3931 ORD(glDrawElements);
3561 ORD(glEnable); 3932// ORD(glEnable);
3562 ORD(glEnableVertexAttribArray); 3933 ORD(glEnableVertexAttribArray);
3563 ORD(glFinish); 3934 ORD(glFinish);
3564 ORD(glFlush); 3935 ORD(glFlush);
@@ -3612,7 +3983,7 @@ eng_gl_api_get(void *data)
3612// ORD(glReleaseShaderCompiler); 3983// ORD(glReleaseShaderCompiler);
3613 ORD(glRenderbufferStorage); 3984 ORD(glRenderbufferStorage);
3614 ORD(glSampleCoverage); 3985 ORD(glSampleCoverage);
3615 ORD(glScissor); 3986// ORD(glScissor);
3616// ORD(glShaderBinary); 3987// ORD(glShaderBinary);
3617 ORD(glShaderSource); 3988 ORD(glShaderSource);
3618 ORD(glStencilFunc); 3989 ORD(glStencilFunc);
@@ -3657,7 +4028,7 @@ eng_gl_api_get(void *data)
3657 ORD(glVertexAttrib4f); 4028 ORD(glVertexAttrib4f);
3658 ORD(glVertexAttrib4fv); 4029 ORD(glVertexAttrib4fv);
3659 ORD(glVertexAttribPointer); 4030 ORD(glVertexAttribPointer);
3660 ORD(glViewport); 4031// ORD(glViewport);
3661#undef ORD 4032#undef ORD
3662 4033
3663#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_) 4034#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, glsym_)
@@ -3717,6 +4088,14 @@ eng_gl_api_get(void *data)
3717 ORD(glBindFramebuffer); 4088 ORD(glBindFramebuffer);
3718 ORD(glBindRenderbuffer); 4089 ORD(glBindRenderbuffer);
3719 4090
4091 ORD(glClear);
4092 ORD(glClearColor);
4093 ORD(glEnable);
4094 ORD(glDisable);
4095 ORD(glReadPixels);
4096 ORD(glScissor);
4097 ORD(glViewport);
4098
3720 // GLES2.0 API compat on top of desktop gl 4099 // GLES2.0 API compat on top of desktop gl
3721 ORD(glClearDepthf); 4100 ORD(glClearDepthf);
3722 ORD(glDepthRangef); 4101 ORD(glDepthRangef);
@@ -3739,6 +4118,24 @@ eng_gl_api_get(void *data)
3739 return &gl_funcs; 4118 return &gl_funcs;
3740} 4119}
3741 4120
4121static void
4122eng_gl_img_obj_set(void *data, void *image, int has_alpha)
4123{
4124 Render_Engine *re = (Render_Engine *)data;
4125
4126 gl_direct_img_obj = NULL;
4127
4128 // Normally direct rendering isn't allowed if alpha is on and
4129 // rotation is not 0. BUT, if override is on, allow it.
4130 if ((has_alpha) || (re->win->gl_context->rot!=0))
4131 {
4132 if (gl_direct_override)
4133 gl_direct_img_obj = image;
4134 }
4135 else
4136 gl_direct_img_obj = image;
4137}
4138
3742static int 4139static int
3743eng_image_load_error_get(void *data __UNUSED__, void *image) 4140eng_image_load_error_get(void *data __UNUSED__, void *image)
3744{ 4141{
@@ -3877,6 +4274,9 @@ module_open(Evas_Module *em)
3877 EINA_LOG_ERR("Can not create a module log domain."); 4274 EINA_LOG_ERR("Can not create a module log domain.");
3878 return 0; 4275 return 0;
3879 } 4276 }
4277 /* Allow alpha for evas gl direct rendering */
4278 if (getenv("EVAS_GL_DIRECT_OVERRIDE")) gl_direct_override = 1;
4279
3880 /* store it for later use */ 4280 /* store it for later use */
3881 func = pfunc; 4281 func = pfunc;
3882 /* now to override methods */ 4282 /* now to override methods */
@@ -3961,6 +4361,7 @@ module_open(Evas_Module *em)
3961 ORD(gl_proc_address_get); 4361 ORD(gl_proc_address_get);
3962 ORD(gl_native_surface_get); 4362 ORD(gl_native_surface_get);
3963 ORD(gl_api_get); 4363 ORD(gl_api_get);
4364 ORD(gl_img_obj_set);
3964 4365
3965 ORD(image_load_error_get); 4366 ORD(image_load_error_get);
3966 4367