big patch from Samsung SAIT (Advanced research group) for async multi-frame
[framework/uifw/evas.git] / src / modules / engines / software_x11 / evas_xlib_outbuf.c
index 6e1ac92..7274c1a 100644 (file)
@@ -25,6 +25,15 @@ static int shmsize = 0;
 static int shmmemlimit = 10 * 1024 * 1024;
 static int shmcountlimit = 32;
 
+#ifdef EVAS_FRAME_QUEUING
+static LK(lock_shmpool);
+#define SHMPOOL_LOCK()         LKL(lock_shmpool)
+#define SHMPOOL_UNLOCK()       LKU(lock_shmpool)
+#else
+#define SHMPOOL_LOCK()
+#define SHMPOOL_UNLOCK()
+#endif
+
 static X_Output_Buffer *
 _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
 {
@@ -46,6 +55,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
    else
      lbytes = ((w + 31) / 32) * 4;
    sz = lbytes * h;
+   SHMPOOL_LOCK();
    EINA_LIST_FOREACH(shmpool, l, xob2)
      {
        int szdif;
@@ -69,8 +79,12 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
          }
      }
    if ((fitness > (100 * 100)) || (!xob))
-     return evas_software_xlib_x_output_buffer_new(d, v, depth, w, h, shm, data);
-
+     {
+        SHMPOOL_UNLOCK();
+        xob = evas_software_xlib_x_output_buffer_new(d, v, depth, w, h, shm, data);
+        return xob;
+     }
+   
    have_xob:
    shmpool = eina_list_remove_list(shmpool, xl);
    xob->w = w;
@@ -80,6 +94,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
    xob->xim->height = xob->h;
    xob->xim->bytes_per_line = xob->bpl;
    shmsize -= xob->psize * (xob->xim->depth / 8);
+   SHMPOOL_UNLOCK();
    return xob;
 }
 
@@ -89,6 +104,7 @@ _unfind_xob(X_Output_Buffer *xob, int sync)
 //   evas_software_xlib_x_output_buffer_free(xob, sync); return;
    if (xob->shm_info)
      {
+        SHMPOOL_LOCK();
        shmpool = eina_list_prepend(shmpool, xob);
        shmsize += xob->psize * xob->xim->depth / 8;
        while ((shmsize > (shmmemlimit)) ||
@@ -103,9 +119,11 @@ _unfind_xob(X_Output_Buffer *xob, int sync)
                  break;
               }
             xob = xl->data;
-            shmpool = eina_list_remove_list(shmpool, xl);
+             shmpool = eina_list_remove_list(shmpool, xl);
+             shmsize -= xob->psize * xob->xim->depth / 8;
             evas_software_xlib_x_output_buffer_free(xob, sync);
          }
+        SHMPOOL_UNLOCK();
      }
    else
      evas_software_xlib_x_output_buffer_free(xob, sync);
@@ -114,6 +132,7 @@ _unfind_xob(X_Output_Buffer *xob, int sync)
 static void
 _clear_xob(int sync)
 {
+   SHMPOOL_LOCK();
    while (shmpool)
      {
        X_Output_Buffer *xob;
@@ -123,16 +142,23 @@ _clear_xob(int sync)
        evas_software_xlib_x_output_buffer_free(xob, sync);
      }
    shmsize = 0;
+   SHMPOOL_UNLOCK();
 }
 
 void
 evas_software_xlib_outbuf_init(void)
 {
+#ifdef EVAS_FRAME_QUEUING
+   LKI(lock_shmpool);
+#endif
 }
 
 void
 evas_software_xlib_outbuf_free(Outbuf *buf)
 {
+#ifdef EVAS_FRAME_QUEUING
+   LKL(buf->priv.lock);
+#endif
    while (buf->priv.pending_writes)
      {
        RGBA_Image *im;
@@ -146,6 +172,9 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
        if (obr->mxob) _unfind_xob(obr->mxob, 0);
        free(obr);
      }
+#ifdef EVAS_FRAME_QUEUING
+   LKU(buf->priv.lock);
+#endif
    evas_software_xlib_outbuf_idle_flush(buf);
    evas_software_xlib_outbuf_flush(buf);
    if (buf->priv.x11.xlib.gc)
@@ -155,6 +184,9 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
    if (buf->priv.pal)
       evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
                                           buf->priv.x11.xlib.vis, buf->priv.pal);
+#ifdef EVAS_FRAME_QUEUING
+   LKD(buf->priv.lock);
+#endif
    free(buf);
    _clear_xob(0);
 }
@@ -331,6 +363,9 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
       evas_software_xlib_outbuf_drawable_set(buf, draw);
       evas_software_xlib_outbuf_mask_set(buf, mask);
    }
+#ifdef EVAS_FRAME_QUEUING
+   LKI(buf->priv.lock);
+#endif
    return buf;
 }
 
@@ -578,7 +613,10 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
      /* FIXME: faster memset! */
      memset(im->image.data, 0, w * h * sizeof(DATA32));
 
-   buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
+#ifdef EVAS_FRAME_QUEUING
+   if (!evas_common_frameq_enabled())
+#endif
+      buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
    return im;
 }
 
@@ -653,6 +691,9 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
                                                       buf->priv.x11.xlib.gcm,
                                                       obr->x, obr->y, 0);
          }
+#ifdef EVAS_FRAME_QUEUING
+     LKL(buf->priv.lock);
+#endif
        while (buf->priv.prev_pending_writes)
          {
             im = buf->priv.prev_pending_writes->data;
@@ -670,6 +711,9 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
             free(obr);
          }
        buf->priv.prev_pending_writes = buf->priv.pending_writes;
+#ifdef EVAS_FRAME_QUEUING
+     LKU(buf->priv.lock);
+#endif
        buf->priv.pending_writes = NULL;
        XFlush(buf->priv.x11.xlib.disp);
 #else
@@ -734,6 +778,9 @@ evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
      }
    else
      {
+#ifdef EVAS_FRAME_QUEUING
+     LKL(buf->priv.lock);
+#endif
        if (buf->priv.prev_pending_writes) XSync(buf->priv.x11.xlib.disp, False);
        while (buf->priv.prev_pending_writes)
          {
@@ -750,6 +797,9 @@ evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
             if (obr->mxob) _unfind_xob(obr->mxob, 0);
             free(obr);
          }
+#ifdef EVAS_FRAME_QUEUING
+     LKU(buf->priv.lock);
+#endif
        _clear_xob(0);
      }
 }
@@ -1036,3 +1086,12 @@ evas_software_xlib_outbuf_alpha_get(Outbuf *buf)
 {
    return buf->priv.x11.xlib.mask;
 }
+
+#ifdef EVAS_FRAME_QUEUING
+void
+evas_software_xlib_outbuf_set_priv(Outbuf *buf, void *cur, void *prev)
+{
+   buf->priv.pending_writes = (Eina_List *)cur;
+}
+
+#endif