found nvidia eat-cpu-bug. glXWaitGL() spins using all cpu it can find,
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 1 Jan 2012 06:47:16 +0000 (06:47 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sun, 1 Jan 2012 06:47:16 +0000 (06:47 +0000)
though nvidia fixed the spinning on glXSwapBuffers() long ago, they
didn't fix this one.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@66710 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/modules/engines/gl_x11/evas_engine.c

index 28d7f45..cb7d104 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
         * Add recursive name find function - evas_object_name_child_find()
 
+2012-01-01  Carsten Haitzler (The Rasterman)
+
+        * Improve CPU use on nvidia drivers when vsyncing. It was
+          actually glXWaitGL() spinning, not glXSwapBuffers(), so this
+          points to a bug in the nvidia drivers where the sleep logic
+          in glXSwapBuffers() hasn't been transferred to glXWaitGL().
+          Avoid use of glXWaitGL() to avoid the nvidia bug.
index abff442..2ffb936 100644 (file)
@@ -1125,12 +1125,12 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
    eng_window_use(re->win);
    evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot);
    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
-/*
+
    RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->w, re->win->h);
    if ((w <= 0) || (h <= 0)) return;
    if (!re->win->draw.redraw)
      {
-#if 0
+#if 1
        re->win->draw.x1 = x;
        re->win->draw.y1 = y;
        re->win->draw.x2 = x + w - 1;
@@ -1150,7 +1150,6 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
        if ((y + h - 1) > re->win->draw.y2) re->win->draw.y2 = y + h - 1;
      }
    re->win->draw.redraw = 1;
- */
 }
 
 static void
@@ -1243,8 +1242,8 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i
 
 //#define FRAMECOUNT 1
 
-#ifdef FRAMECOUNT
-double
+//#ifdef FRAMECOUNT
+static double
 get_time(void)
 {
    struct timeval      timev;
@@ -1252,7 +1251,7 @@ get_time(void)
    gettimeofday(&timev, NULL);
    return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
 }
-#endif
+//#endif
 
 static int safe_native = -1;
 
@@ -1391,44 +1390,48 @@ eng_output_flush(void *data)
      {
         re->info->callback.pre_swap(re->info->callback.data, re->evas);
      }
-/*
-   if ((1)
-//       (re->win->draw.x1 == 0) &&
-//       (re->win->draw.y1 == 0) &&
-//       (re->win->draw.x2 == (re->win->w - 1)) &&
-//       (re->win->draw.y2 == (re->win->h - 1))
-       )
- */
+#if 1
+   if (1)
+#else
+   if ((re->win->draw.x1 == 0) && (re->win->draw.y1 == 0) && (re->win->draw.x2 == (re->win->w - 1)) && (re->win->draw.y2 == (re->win->h - 1)))
+#endif     
      {
+//        double t, t2 = 0.0;
+//        t = get_time();
         glXSwapBuffers(re->win->disp, re->win->win);
-        if (!safe_native) glXWaitGL();
+//        t = get_time() - t;
+//        if (!safe_native)
+//          {
+//             t2 = get_time();
+//             glXWaitGL();
+//             t2 = get_time() - t2;
+//          }
+//        printf("swap: %3.5f (%3.5fms), x wait gl: %3.5f (%3.5fms)\n", 
+//               t, t * 1000.0, t2, t2 * 1000.0);
      }
-/*
    else
      {
 // FIXME: this doesn't work.. why oh why?
         int sx, sy, sw, sh;
 
-        // fimxe - reset when done
-//        glEnable(GL_SCISSOR_TEST);
-        glDrawBuffer(GL_FRONT);
-
         sx = re->win->draw.x1;
         sy = re->win->draw.y1;
         sw = (re->win->draw.x2 - re->win->draw.x1) + 1;
         sh = (re->win->draw.y2 - re->win->draw.y1) + 1;
         sy = re->win->h - sy - sh;
-
-//        glScissor(sx, sy, sw, sh);
+        
+        glPixelZoom(1.0, 1.0);
+        glDisable(GL_BLEND);
+        glDisable(GL_SCISSOR_TEST);
         glRasterPos2i(sx, re->win->h - sy);
+        glReadBuffer(GL_BACK);
+        glDrawBuffer(GL_FRONT);
         glCopyPixels(sx, sy, sw, sh, GL_COLOR);
-        glRasterPos2i(0, 0);
-
-//        glDisable(GL_SCISSOR_TEST);
         glDrawBuffer(GL_BACK);
+        glReadBuffer(GL_BACK);
+        glRasterPos2i(0, 0);
         glFlush();
      }
- */
    if (re->info->callback.post_swap)
      {
         re->info->callback.post_swap(re->info->callback.data, re->evas);