[gtk+/broadway: 35/71] [broadway] Send diffs as bilevel rgba instead of true diff
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/broadway: 35/71] [broadway] Send diffs as bilevel rgba instead of true diff
- Date: Thu, 25 Nov 2010 21:18:12 +0000 (UTC)
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]