From: "Sung W. Park" <sungwoo@gmail.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 25 Aug 2011 06:30:52 +0000 (06:30 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 25 Aug 2011 06:30:52 +0000 (06:30 +0000)
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: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@62780 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/Evas_GL.h
src/modules/engines/gl_x11/evas_engine.c

index 27b847b..1307b90 100644 (file)
@@ -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."
index d766aac..d440c23 100644 (file)
@@ -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);
 }