[gtk+/broadway: 242/246] broadway: double buffer window updates
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/broadway: 242/246] broadway: double buffer window updates
- Date: Tue, 15 Mar 2011 12:01:22 +0000 (UTC)
commit e3a2176a1fe5363560fc646d4ae2d4690fbd4c8f
Author: Alexander Larsson <alexl redhat com>
Date: Tue Mar 15 09:50:07 2011 +0100
broadway: double buffer window updates
Ensure that we're writing all the updates for a single rendering op
in one go without callbacks inbetween. That way some rendering will
be delayed, but the user will never see partial renderings.
gdk/broadway/broadway.c | 15 ++++
gdk/broadway/broadway.h | 2 +
gdk/broadway/broadway.js | 138 +++++++++++++++++++++++-------------
gdk/broadway/gdkwindow-broadway.c | 2 +
4 files changed, 107 insertions(+), 50 deletions(-)
---
diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c
index bc78de1..d5e944d 100644
--- a/gdk/broadway/broadway.c
+++ b/gdk/broadway/broadway.c
@@ -1088,6 +1088,21 @@ broadway_output_put_rgba (BroadwayOutput *output, int id, int x, int y,
free (rects);
}
+void
+broadway_output_surface_flush (BroadwayOutput *output,
+ int id)
+{
+ char buf[HEADER_LEN + 3];
+ int p;
+
+ p = write_header (output, buf, 'f');
+ append_uint16 (id, buf, &p);
+
+ assert (p == sizeof (buf));
+
+ broadway_output_write (output, buf, sizeof (buf));
+}
+
#if 0
static void
send_image_a (BroadwayOutput *output, int id, int x, int y,
diff --git a/gdk/broadway/broadway.h b/gdk/broadway/broadway.h
index c750a24..635fc91 100644
--- a/gdk/broadway/broadway.h
+++ b/gdk/broadway/broadway.h
@@ -49,6 +49,8 @@ void broadway_output_put_rgba (BroadwayOutput *output,
int h,
int byte_stride,
void *data);
+void broadway_output_surface_flush (BroadwayOutput *output,
+ int id);
void broadway_output_copy_rectangles (BroadwayOutput *output,
int id,
BroadwayRect *rects,
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index cd81d09..89242e3 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -101,6 +101,7 @@ function initContext(canvas, x, y, id)
var context = canvas.getContext("2d");
context.globalCompositeOperation = "source-over";
document.body.appendChild(canvas);
+ context.drawQueue = [];
return context;
}
@@ -146,6 +147,63 @@ function getButtonMask (button) {
return 0;
}
+function flushSurface(surface)
+{
+ var commands = surface.drawQueue;
+ surface.queue = [];
+ var i = 0;
+ for (i = 0; i < commands.length; i++) {
+ var cmd = commands[i];
+ var context = surfaces[cmd.id];
+ switch (cmd.op) {
+ /* put image data surface */
+ case 'i':
+ context.globalCompositeOperation = "source-over";
+ context.drawImage(cmd.img, cmd.x, cmd.y);
+ break;
+
+ /* copy rects */
+ case 'b':
+ context.save();
+ context.beginPath();
+
+ var minx;
+ var miny;
+ var maxx;
+ var maxy;
+ for (var j = 0; j < cmd.rects.length; j++) {
+ var rect = cmd.rects[j];
+ context.rect(rect.x, rect.y, rect.w, rect.h);
+ if (j == 0) {
+ minx = rect.x;
+ miny = rect.y;
+ maxx = rect.x + rect.w;
+ maxy = rect.y + rect.h;
+ } else {
+ if (rect.x < minx)
+ minx = rect.x;
+ if (rect.y < miny)
+ miny = rect.y;
+ if (rect.x + rect.w > maxx)
+ maxx = rect.x + rect.w;
+ if (rect.y + rect.h > maxy)
+ maxy = rect.y + rect.h;
+ }
+ }
+ context.clip();
+ context.globalCompositeOperation = "copy";
+ context.drawImage(context.canvas,
+ minx - cmd.dx, miny - cmd.dy, maxx - minx, maxy - miny,
+ minx, miny, maxx - minx, maxy - miny);
+ context.restore();
+ break;
+
+ default:
+ alert("Unknown drawing op " + cmd.op);
+ }
+ }
+}
+
function handleCommands(cmd_obj)
{
var cmd = cmd_obj.data;
@@ -218,30 +276,31 @@ function handleCommands(cmd_obj)
i = i + 3;
var h = base64_16(cmd, i);
i = i + 3;
+ flushSurface(surfaces[id]);
surfaces[id].canvas.width = w;
surfaces[id].canvas.height = h;
break;
/* put image data surface */
case 'i':
- var id = base64_16(cmd, i);
+ var q = new Object();
+ q.op = 'i';
+ q.id = base64_16(cmd, i);
i = i + 3;
- var x = base64_16(cmd, i);
+ q.x = base64_16(cmd, i);
i = i + 3;
- var y = base64_16(cmd, i);
+ q.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;
- surfaces[id].globalCompositeOperation = "source-over";
- if (img.complete) {
- surfaces[id].drawImage(img, x, y);
- } else {
+ q.img = new Image();
+ q.img.src = url;
+ surfaces[q.id].drawQueue.push(q);
+ if (!q.img.complete) {
cmd_obj.pos = i;
- img.onload = function() { surfaces[id].drawImage(img, x, y); handleOutstanding(); };
+ q.img.onload = function() { handleOutstanding(); };
return false;
}
@@ -249,62 +308,41 @@ function handleCommands(cmd_obj)
/* copy rects */
case 'b':
- var id = base64_16(cmd, i);
+ var q = new Object();
+ q.op = 'b';
+ q.id = base64_16(cmd, i);
i = i + 3;
var nrects = base64_16(cmd, i);
i = i + 3;
- var context = surfaces[id];
- context.save();
- context.beginPath();
-
- var minx;
- var miny;
- var maxx;
- var maxy;
+ q.rects = [];
for (var r = 0; r < nrects; r++) {
- var x = base64_16(cmd, i);
+ var rect = new Object();
+ rect.x = base64_16(cmd, i);
i = i + 3;
- var y = base64_16(cmd, i);
+ rect.y = base64_16(cmd, i);
i = i + 3;
- var w = base64_16(cmd, i);
+ rect.w = base64_16(cmd, i);
i = i + 3;
- var h = base64_16(cmd, i);
+ rect.h = base64_16(cmd, i);
i = i + 3;
- context.rect(x, y, w, h);
-
- if (r == 0) {
- minx = x;
- miny = y;
- maxx = x + w;
- maxy = y + h;
- } else {
- if (x < minx)
- minx = x;
- if (y < miny)
- miny = y;
- if (x + w > maxx)
- maxx = x + w;
- if (y + h > maxy)
- maxy = y + h;
- }
+ q.rects.push (rect);
}
- context.clip();
-
- var dx = base64_16s(cmd, i);
+ q.dx = base64_16s(cmd, i);
i = i + 3;
- var dy = base64_16s(cmd, i);
+ q.dy = base64_16s(cmd, i);
i = i + 3;
+ surfaces[q.id].drawQueue.push(q);
+ break;
- context.globalCompositeOperation = "copy";
- context.drawImage(context.canvas,
- minx - dx, miny - dy, maxx - minx, maxy - miny,
- minx, miny, maxx - minx, maxy - miny);
+ case 'f': // Flush surface
+ var id = base64_16(cmd, i);
+ i = i + 3;
- context.restore();
- break;
+ flushSurface(surfaces[id]);
+ break;
case 'q': // Query pointer
var id = base64_16(cmd, i);
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
index c42bbf2..b986697 100644
--- a/gdk/broadway/gdkwindow-broadway.c
+++ b/gdk/broadway/gdkwindow-broadway.c
@@ -153,6 +153,8 @@ window_data_send (BroadwayOutput *output, GdkWindowImplBroadway *impl)
cairo_image_surface_get_data (impl->surface));
}
+ broadway_output_surface_flush (output, impl->id);
+
cr = cairo_create (impl->last_surface);
cairo_set_source_surface (cr, impl->surface, 0, 0);
cairo_paint (cr);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]