[gtk+/broadway: 35/71] [broadway] Send diffs as bilevel rgba instead of true diff



commit e6c340519c67940abd25b27fb7b96eb0e225670a
Author: Alexander Larsson <alexl redhat com>
Date:   Sun Nov 21 19:52:05 2010 +0100

    [broadway] Send diffs as bilevel rgba instead of true diff
    
    The true diff only works if the destination keeps perfect 32bit
    canvas data, which is not always true. So, instead we send only
    changed pixels, masking the others to 0 via alpha 0.

 gdk/broadway/broadway-demo.c      |   24 ++++++-----
 gdk/broadway/broadway.c           |   82 +++++++++++++-----------------------
 gdk/broadway/broadway.h           |    8 ----
 gdk/broadway/broadway.js          |   51 +----------------------
 gdk/broadway/gdkwindow-broadway.c |   30 ++++++++------
 5 files changed, 61 insertions(+), 134 deletions(-)
---
diff --git a/gdk/broadway/broadway-demo.c b/gdk/broadway/broadway-demo.c
index 0c4cd1c..959c719 100644
--- a/gdk/broadway/broadway-demo.c
+++ b/gdk/broadway/broadway-demo.c
@@ -5,14 +5,15 @@
 #include "broadway.h"
 #include <math.h>
 #include <unistd.h>
+#include <stdint.h>
 #include <cairo.h>
 
 static void
 diff_surfaces (cairo_surface_t *surface,
 	       cairo_surface_t *old_surface)
 {
-  unsigned char *data, *old_data;
-  unsigned char *line, *old_line;
+  uint8_t *data, *old_data;
+  uint32_t *line, *old_line;
   int w, h, stride, old_stride;
   int x, y;
 
@@ -27,16 +28,17 @@ diff_surfaces (cairo_surface_t *surface,
 
   for (y = 0; y < h; y++)
     {
-      line = data;
-      old_line = old_data;
+      line = (uint32_t *)data;
+      old_line = (uint32_t *)old_data;
 
       for (x = 0; x < w; x++)
 	{
-	  int j;
-	  for (j = 0; j < 4; j++)
-	    old_line[j] = line[j] - old_line[j];
-	  line += 4;
-	  old_line += 4;
+	  if (*line & 0xffffff == *old_line & 0xffffff)
+	    *old_line = 0;
+	  else
+	    *old_line = *line | 0xff000000;
+	  line ++;
+	  old_line ++;
 	}
 
       data += stride;
@@ -181,8 +183,8 @@ demo2 (BroadwayClient *client)
 	{
 	  diff_surfaces (surface,
 			 old_surface);
-	  broadway_client_put_delta_rgb (client, 0, 0, 0, 800, 600, 800*4,
-					 cairo_image_surface_get_data(old_surface));
+	  broadway_client_put_rgba (client, 0, 0, 0, 800, 600, 800*4,
+				    cairo_image_surface_get_data(old_surface));
 	}
       broadway_client_move_surface (client, 0, 100 + i, 100 + i);
 
diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c
index baaae97..95d8b05 100644
--- a/gdk/broadway/broadway.c
+++ b/gdk/broadway/broadway.c
@@ -834,12 +834,12 @@ broadway_client_put_rgb (BroadwayClient *client,  int id, int x, int y,
 }
 
 static void
-rgb_autocrop (unsigned char *data,
-	      int byte_stride,
-	      int *x_arg, int *y_arg,
-	      int *w_arg, int *h_arg)
+rgba_autocrop (unsigned char *data,
+	       int byte_stride,
+	       int *x_arg, int *y_arg,
+	       int *w_arg, int *h_arg)
 {
-  unsigned char *line;
+  uint32_t *line;
   int w, h;
   int x, y, xx, yy;
   boolean non_zero;
@@ -851,16 +851,16 @@ rgb_autocrop (unsigned char *data,
 
   while (h > 0)
     {
-      line = data + y * byte_stride + x * 4;
+      line = (uint32_t *)(data + y * byte_stride + x * 4);
 
       non_zero = FALSE;
       for (xx = 0; xx < w; xx++)
 	{
-	  if (line[1] != 0 || line[2] != 0 || line[3] != 0) {
+	  if (*line != 0) {
 	    non_zero = TRUE;
 	    break;
 	  }
-	  line += 4;
+	  line++;
 	}
 
       if (non_zero)
@@ -872,16 +872,16 @@ rgb_autocrop (unsigned char *data,
 
   while (h > 0)
     {
-      line = data + (y + h - 1) * byte_stride + x * 4;
+      line = (uint32_t *)(data + (y + h - 1) * byte_stride + x * 4);
 
       non_zero = FALSE;
       for (xx = 0; xx < w; xx++)
 	{
-	  if (line[1] != 0 || line[2] != 0 || line[3] != 0) {
+	  if (*line != 0) {
 	    non_zero = TRUE;
 	    break;
 	  }
-	  line += 4;
+	  line++;
 	}
 
       if (non_zero)
@@ -891,16 +891,16 @@ rgb_autocrop (unsigned char *data,
 
   while (w > 0)
     {
-      line = data + y * byte_stride + x * 4;
+      line = (uint32_t *)(data + y * byte_stride + x * 4);
 
       non_zero = FALSE;
       for (yy = 0; yy < h; yy++)
 	{
-	  if (line[1] != 0 || line[2] != 0 || line[3] != 0) {
+	  if (*line != 0) {
 	    non_zero = TRUE;
 	    break;
 	  }
-	  line += byte_stride;
+	  line += byte_stride / 4;
 	}
 
       if (non_zero)
@@ -912,16 +912,16 @@ rgb_autocrop (unsigned char *data,
 
   while (w > 0)
     {
-      line = data + y * byte_stride + (x + w - 1) * 4;
+      line = (uint32_t *)(data + y * byte_stride + (x + w - 1) * 4);
 
       non_zero = FALSE;
       for (yy = 0; yy < h; yy++)
 	{
-	  if (line[1] != 0 || line[2] != 0 || line[3] != 0) {
+	  if (*line != 0) {
 	    non_zero = TRUE;
 	    break;
 	  }
-	  line += byte_stride;
+	  line += byte_stride / 4;
 	}
 
       if (non_zero)
@@ -936,54 +936,32 @@ rgb_autocrop (unsigned char *data,
 }
 
 void
-broadway_client_put_delta_rgb (BroadwayClient *client,  int id, int dest_x, int dest_y,
-			       int w, int h, int byte_stride, void *data)
+broadway_client_put_rgba (BroadwayClient *client,  int id, int x, int y,
+			  int w, int h, int byte_stride, void *data)
 {
   char buf[16];
   size_t len;
   char *url;
-  int src_x, src_y;
+  int crop_x, crop_y;
 
-  src_x = 0;
-  src_y = 0;
+  crop_x = 0;
+  crop_y = 0;
 
-  rgb_autocrop (data,
-		byte_stride,
-		&src_x, &src_y, &w, &h);
+  printf ("pre crop: %dx%d\n", w, h);
+  rgba_autocrop (data,
+		 byte_stride,
+		 &crop_x, &crop_y, &w, &h);
+  printf ("post crop: %dx%d %d,%d\n", w, h, crop_x, crop_y);
 
   if (w == 0 || h == 0)
     return;
 
-  data = (uint8_t *)data + src_x * 4 + src_y * byte_stride;
-
-  buf[0] = 'D';
-  base64_uint16(id, &buf[1]);
-  base64_uint16(dest_x + src_x, &buf[4]);
-  base64_uint16(dest_y + src_y, &buf[7]);
-
-  url = to_png_rgb (w, h, byte_stride, (uint32_t*)data);
-  len = strlen (url);
-  base64_uint32(len, &buf[10]);
-
-  broadway_client_write (client, buf, 16);
-
-  broadway_client_write (client, url, len);
-
-  free (url);
-}
-
-void
-broadway_client_put_rgba (BroadwayClient *client,  int id, int x, int y,
-			  int w, int h, int byte_stride, void *data)
-{
-  char buf[16];
-  size_t len;
-  char *url;
+  data = (uint8_t *)data + crop_x * 4 + crop_y * byte_stride;
 
   buf[0] = 'i';
   base64_uint16(id, &buf[1]);
-  base64_uint16(x, &buf[4]);
-  base64_uint16(y, &buf[7]);
+  base64_uint16(x + crop_x, &buf[4]);
+  base64_uint16(y + crop_y, &buf[7]);
 
   url = to_png_rgba (w, h, byte_stride, (uint32_t*)data);
   len = strlen (url);
diff --git a/gdk/broadway/broadway.h b/gdk/broadway/broadway.h
index 8ae0d6d..78154d2 100644
--- a/gdk/broadway/broadway.h
+++ b/gdk/broadway/broadway.h
@@ -39,14 +39,6 @@ void            broadway_client_put_rgba        (BroadwayClient *client,
 						 int             h,
 						 int             byte_stride,
 						 void           *data);
-void            broadway_client_put_delta_rgb   (BroadwayClient *client,
-						 int             id,
-						 int             dest_x,
-						 int             dest_y,
-						 int             w,
-						 int             h,
-						 int             byte_stride,
-						 void           *data);
 void            broadway_client_copy_rectangles (BroadwayClient *client,
 						 int             id,
 						 BroadwayRect   *rects,
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 0a2e150..cbd11e4 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -68,31 +68,6 @@ var surfaces = {};
 var outstanding_commands = new Array();
 var input_socket = null;
 
-function apply_delta(id, img, x, y)
-{
-  var tmp_surface = document.createElement("canvas");
-  var w = img.width;
-  var h = img.height;
-  tmp_surface.width = w;
-  tmp_surface.height = h;
-
-  tmp_context = tmp_surface.getContext("2d");
-  tmp_context.drawImage(img, 0, 0);
-
-  var data = surfaces[id].getImageData(x, y, w, h);
-  var d = data.data
-  var delta = tmp_context.getImageData(0, 0, w, h).data;
-  var imax = w * h * 4;
-  for (var i = 0; i < imax; i += 4) {
-    d[i  ] = (d[i  ] + delta[i  ]) & 0xff;
-    d[i+1] = (d[i+1] + delta[i+1]) & 0xff;
-    d[i+2] = (d[i+2] + delta[i+2]) & 0xff;
-    d[i+3] = 255;
-  }
-  surfaces[id].putImageData(data, x, y);
-  delete tmp_surface
-}
-
 function initContext(canvas, x, y, id)
 {
   canvas.surface_id = id;
@@ -101,7 +76,7 @@ function initContext(canvas, x, y, id)
   canvas.style["left"] = y + "px"
   canvas.style["display"] = "none"
   context = canvas.getContext("2d")
-  context.globalCompositeOperation = "copy"
+  context.globalCompositeOperation = "src-over"
   context.fillRect(0, 0, canvas.width, canvas.height);
   document.body.appendChild(canvas)
 
@@ -194,30 +169,6 @@ function handleCommands(cmd_obj)
 
         break;
 
-      /* put delta image data surface */
-      case 'D':
-        var id = base64_16(cmd, i);
-        i = i + 3;
-        var x = base64_16(cmd, i);
-        i = i + 3;
-        var y = base64_16(cmd, i);
-        i = i + 3;
-        var size = base64_32(cmd, i);
-        i = i + 6;
-	var url = cmd.slice(i, i + size);
-	i = i + size;
-        var img = new Image();
-	img.src = url
-	if (img.complete) {
-	  apply_delta(id, img, x, y);
-	} else {
-	  cmd_obj.pos = i;
-          img.onload = function() { apply_delta(id, img, x, y); handleOutstanding(); }
-	  return false
-	}
-
-        break;
-
       /* copy rects */
       case 'b':
         var id = base64_16(cmd, i);
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
index b8937b5..3814750 100644
--- a/gdk/broadway/gdkwindow-broadway.c
+++ b/gdk/broadway/gdkwindow-broadway.c
@@ -87,7 +87,7 @@ diff_surfaces (cairo_surface_t *surface,
 	       cairo_surface_t *old_surface)
 {
   guint8 *data, *old_data;
-  guint8 *line, *old_line;
+  guint32 *line, *old_line;
   int w, h, stride, old_stride;
   int x, y;
 
@@ -102,16 +102,17 @@ diff_surfaces (cairo_surface_t *surface,
 
   for (y = 0; y < h; y++)
     {
-      line = data;
-      old_line = old_data;
+      line = (guint32 *)data;
+      old_line = (guint32 *)old_data;
 
       for (x = 0; x < w; x++)
 	{
-	  int j;
-	  for (j = 0; j < 4; j++)
-	    old_line[j] = line[j] - old_line[j];
-	  line += 4;
-	  old_line += 4;
+	  if ((*line & 0xffffff) == (*old_line & 0xffffff))
+	    *old_line = 0;
+	  else
+	    *old_line = *line | 0xff000000;
+	  line ++;
+	  old_line ++;
 	}
 
       data += stride;
@@ -127,15 +128,18 @@ window_data_send (BroadwayClient *client, GdkWindowImplBroadway *impl)
   GdkDrawableImplBroadway *drawable_impl = GDK_DRAWABLE_IMPL_BROADWAY (impl);
   cairo_t *cr;
 
+  if (drawable_impl->surface == NULL)
+    return;
+
   if (impl->last_synced)
     {
       diff_surfaces (drawable_impl->surface,
 		     drawable_impl->last_surface);
-      broadway_client_put_delta_rgb (client, impl->id, 0, 0,
-				     cairo_image_surface_get_width (drawable_impl->last_surface),
-				     cairo_image_surface_get_height (drawable_impl->last_surface),
-				     cairo_image_surface_get_stride (drawable_impl->last_surface),
-				     cairo_image_surface_get_data (drawable_impl->last_surface));
+      broadway_client_put_rgba (client, impl->id, 0, 0,
+				cairo_image_surface_get_width (drawable_impl->last_surface),
+				cairo_image_surface_get_height (drawable_impl->last_surface),
+				cairo_image_surface_get_stride (drawable_impl->last_surface),
+				cairo_image_surface_get_data (drawable_impl->last_surface));
     }
   else
     {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]