From 14ab2c737715ef5935e39d01362130bf3f06aa96 Mon Sep 17 00:00:00 2001 From: raster Date: Thu, 25 Aug 2011 06:30:52 +0000 Subject: [PATCH] From: "Sung W. Park" Subject: [E-devel] [Review] [Patch] Evas_GL bug fixes/updates I've fixed some minor issues that I've been pushing off for later. The patch does the following: 1. Evas_GL and Evas had an issue where the viewport parameters were being reset in the wrong context. Previously, this issue was temporarily patched by flushing evas' pipeline and setting evas_gl_common_context_use(NULL) in EvasGL's make current. I know, it was pretty hacky. It turns out that in evas_engine, there was a code evas_gl_common_context_resize(NULL) without doing eng_window_use() first. So i've added that part and problem went was resolved properly. :-) 2. Naturally, I've taken out the temporary patch from 1. 3. I've added code that took care of glBindFramebuffer(..., fbo) where the fbo had to be saved and restored in case the user wanted to use his own fbo. Also, I've had to take care of the case when fbo is 0 since 0 need to point to evas_gl surface. 4. I've updated make_current a little as well. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@62780 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Evas_GL.h | 21 ++++++ src/modules/engines/gl_x11/evas_engine.c | 120 +++++++++++++++++++------------ 2 files changed, 97 insertions(+), 44 deletions(-) diff --git a/src/lib/Evas_GL.h b/src/lib/Evas_GL.h index 27b847b..1307b90 100644 --- a/src/lib/Evas_GL.h +++ b/src/lib/Evas_GL.h @@ -926,6 +926,27 @@ typedef signed long int GLsizeiptr; // Changed khronos_ssize_t #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +//---------------------------// +// GLES extension defines + +/* GL_EXT_read_format_bgra */ +#ifndef GL_EXT_read_format_bgra +#define GL_BGRA_EXT 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif + +/* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif + +/* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + #else # ifndef EVAS_GL_NO_GL_H_CHECK # error "You may only include either Evas_GL.h OR use your native OpenGL's headers. If you use Evas to do GL, then you cannot use the native gl headers." diff --git a/src/modules/engines/gl_x11/evas_engine.c b/src/modules/engines/gl_x11/evas_engine.c index d766aac..d440c23 100644 --- a/src/modules/engines/gl_x11/evas_engine.c +++ b/src/modules/engines/gl_x11/evas_engine.c @@ -62,13 +62,15 @@ struct _Render_Engine_GL_Context #else GLXContext context; #endif - GLuint fbo; + GLuint context_fbo; + GLuint current_fbo; Render_Engine_GL_Surface *current_sfc; }; static int initted = 0; static int gl_wins = 0; +static Render_Engine_GL_Context *current_evgl_ctx; #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) @@ -539,6 +541,7 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) Render_Engine *re; re = (Render_Engine *)data; + eng_window_use(re->win); evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot); /* smple bounding box */ RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->w, re->win->h); @@ -2257,7 +2260,7 @@ _attach_fbo_surface(Render_Engine *data __UNUSED__, int fb_status; // FBO - glBindFramebuffer(GL_FRAMEBUFFER, ctx->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, ctx->context_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sfc->rt_tex, 0); @@ -2492,7 +2495,7 @@ eng_gl_context_create(void *data, void *share_context) #endif ctx->initialized = 0; - ctx->fbo = 0; + ctx->context_fbo = 0; ctx->current_sfc = NULL; return ctx; @@ -2523,8 +2526,8 @@ eng_gl_context_destroy(void *data, void *context) } // 2. Delete the FBO - if (glIsBuffer(ctx->fbo)) - glDeleteBuffers(1, &ctx->fbo); + if (glIsBuffer(ctx->context_fbo)) + glDeleteBuffers(1, &ctx->context_fbo); // 3. Destroy the Context #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) @@ -2565,28 +2568,6 @@ eng_gl_make_current(void *data, void *surface, void *context) sfc = (Render_Engine_GL_Surface*)surface; ctx = (Render_Engine_GL_Context*)context; - // Flush remainder of what's in Evas' pipeline - if (re->win) - { -#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - if ((eglGetCurrentContext() == re->win->egl_context[0]) || - (eglGetCurrentSurface(EGL_READ) == re->win->egl_surface[0]) || - (eglGetCurrentSurface(EGL_DRAW) == re->win->egl_surface[0])) - { - evas_gl_common_context_use(re->win->gl_context); - evas_gl_common_context_flush(re->win->gl_context); - } -#else - if (glXGetCurrentContext() == re->win->context) - { - evas_gl_common_context_use(re->win->gl_context); - evas_gl_common_context_flush(re->win->gl_context); - } -#endif - eng_window_use(NULL); - evas_gl_common_context_use(NULL); - } - // Unset surface/context if ((!sfc) || (!ctx)) { @@ -2601,53 +2582,86 @@ eng_gl_make_current(void *data, void *surface, void *context) ERR("xxxMakeCurrent() failed!"); return 0; } + + ctx->current_sfc = NULL; + sfc->current_ctx = NULL; + current_evgl_ctx = NULL; return ret; } // Don't do a make current if it's already current - ret = 1; #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) - if ((eglGetCurrentContext() != ctx->context)) - ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], - re->win->egl_surface[0], ctx->context); + if ((eglGetCurrentContext() == ctx->context) && + (eglGetCurrentSurface(EGL_READ) == re->win->egl_surface[0]) && + (eglGetCurrentSurface(EGL_DRAW) == re->win->egl_surface[0]) ) + { + + DBG("Context same\n"); + return 1; + } #else - if (glXGetCurrentContext() != ctx->context) - ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); + if ((glXGetCurrentContext() == ctx->context) && + (glXGetCurrentDrawable() == re->win->win) ) + { + DBG("Context same\n"); + return 1; + } #endif + + + // Flush remainder of what's in Evas' pipeline + if (re->win) + eng_window_use(NULL); + + + // Set the context current +#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) + ret = eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], + re->win->egl_surface[0], ctx->context); if (!ret) { ERR("xxxMakeCurrent() failed!"); return 0; } +#else + ret = glXMakeCurrent(re->info->info.display, re->win->win, ctx->context); + if (!ret) + { + ERR("xxxMakeCurrent() failed!"); + return 0; + } +#endif // Create FBO if not already created if (!ctx->initialized) { - glGenFramebuffers(1, &ctx->fbo); + glGenFramebuffers(1, &ctx->context_fbo); ctx->initialized = 1; } // Attach FBO if it hasn't been attached or if surface changed - if ((!sfc->fbo_attached) || (ctx != sfc->current_ctx)) + if ((!sfc->fbo_attached) || (ctx->current_sfc != sfc)) { if (!_attach_fbo_surface(re, sfc, ctx)) { ERR("_attach_fbo_surface() failed."); return 0; } + + 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 ctx->current_sfc = sfc; sfc->current_ctx = ctx; - - // Bind FBO - glBindFramebuffer(GL_FRAMEBUFFER, ctx->fbo); -#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX) -#else - //glDrawBuffer(GL_COLOR_ATTACHMENT0); -#endif + current_evgl_ctx = ctx; return 1; } @@ -2692,14 +2706,32 @@ eng_gl_native_surface_get(void *data, void *surface, void *native_surface) static void evgl_glBindFramebuffer(GLenum target, GLuint framebuffer) { - // Add logic to take care when framebuffer=0 - glBindFramebuffer(target, framebuffer); + Render_Engine_GL_Context *ctx = current_evgl_ctx; + + // Take care of BindFramebuffer 0 issue + if (framebuffer==0) + { + if (ctx) + { + glBindFramebuffer(target, ctx->context_fbo); + ctx->current_fbo = 0; + } + } + else + { + glBindFramebuffer(target, framebuffer); + + // Save this for restore when doing make current + if (ctx) + ctx->current_fbo = framebuffer; + } } static void evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer) { // Add logic to take care when renderbuffer=0 + // On a second thought we don't need this glBindRenderbuffer(target, renderbuffer); } -- 2.7.4