summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2006-07-09 17:38:34 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2006-07-09 17:38:34 +0000
commit0fe0a709ceeae77cc5d91aab318aec27320e09af (patch)
treefdecbdf035cce3959707e14098f5436e82096818 /riscos
parent5bbd5f259ee7bc128d9b7436e7c864606b8d4d66 (diff)
downloadnetsurf-0fe0a709ceeae77cc5d91aab318aec27320e09af.tar.gz
netsurf-0fe0a709ceeae77cc5d91aab318aec27320e09af.tar.bz2
Join update boxes if possible to decrease rendering time (optimise bouncing bunny testcase.)
svn path=/trunk/netsurf/; revision=2724
Diffstat (limited to 'riscos')
-rw-r--r--riscos/gui.c3
-rw-r--r--riscos/gui.h1
-rw-r--r--riscos/window.c276
3 files changed, 177 insertions, 103 deletions
diff --git a/riscos/gui.c b/riscos/gui.c
index 53fd4ea74..3e8efca12 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -862,7 +862,8 @@ void gui_poll(bool active)
gui_last_poll = clock();
ro_gui_handle_event(event, &block);
schedule_run();
-
+ ro_gui_window_update_boxes();
+
if (gui_reformat_pending && event == wimp_NULL_REASON_CODE)
ro_gui_window_process_reformats();
else if (bitmap_maintenance_priority ||
diff --git a/riscos/gui.h b/riscos/gui.h
index f7338c42d..b5665dcda 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -162,6 +162,7 @@ void ro_gui_window_set_scale(struct gui_window *g, float scale);
void ro_gui_window_iconise(struct gui_window *g,
wimp_full_message_window_info *wi);
bool ro_gui_window_navigate_up(struct gui_window *g, const char *url);
+void ro_gui_window_update_boxes(void);
/* in history.c */
void ro_gui_history_init(void);
diff --git a/riscos/window.c b/riscos/window.c
index 255cee5c0..aa917f9d4 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -86,7 +86,19 @@ static browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons);
static bool ro_gui_window_import_text(struct gui_window *g, const char *filename,
bool toolbar);
+struct update_box {
+ int x0;
+ int y0;
+ int x1;
+ int y1;
+ bool use_buffer;
+ struct gui_window *g;
+ union content_msg_data data;
+ struct update_box *next;
+};
+struct update_box *pending_updates;
+#define MARGIN 4
/**
* Create and open a new browser window.
@@ -561,128 +573,188 @@ void ro_gui_window_redraw(struct gui_window *g, wimp_draw *redraw)
/**
- * Redraw an area of a window.
- *
- * \param g gui_window
- * \param data content_msg_data union with filled in redraw data
+ * Redraw any pending update boxes.
*/
-
-void gui_window_update_box(struct gui_window *g,
- const union content_msg_data *data)
-{
- struct content *c = g->bw->current_content;
+void ro_gui_window_update_boxes(void) {
+ struct content *c;
osbool more;
bool clear_background = false;
bool use_buffer;
wimp_draw update;
int clip_x0, clip_y0, clip_x1, clip_y1;
os_error *error;
+ struct update_box *cur;
+ struct gui_window *g;
+ const union content_msg_data *data;
+
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ g = cur->g;
+ c = g->bw->current_content;
+ data = &cur->data;
+ use_buffer = cur->use_buffer;
+ if (!c)
+ continue;
- /* in some cases an update can be triggered before a content has fully
- * loaded, so current_content is 0 */
- if (!c)
- return;
-
- update.w = g->window;
- update.box.x0 = floorf(data->redraw.x * 2 * g->option.scale);
- update.box.y0 = -ceilf((data->redraw.y + data->redraw.height) * 2 *
- g->option.scale);
- update.box.x1 = ceilf((data->redraw.x + data->redraw.width) * 2 *
- g->option.scale) + 1;
- update.box.y1 = -floorf(data->redraw.y * 2 * g->option.scale) + 1;
+ update.w = g->window;
+ update.box.x0 = cur->x0;
+ update.box.y0 = cur->y0;
+ update.box.x1 = cur->x1;
+ update.box.y1 = cur->y1;
- error = xwimp_update_window(&update, &more);
- if (error) {
- LOG(("xwimp_update_window: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-
- /* Set the current redraw gui_window to get options from
- */
- ro_gui_current_redraw_gui = g;
- current_redraw_browser = g->bw;
- use_buffer = (data->redraw.full_redraw) &&
- (g->option.buffer_everything || g->option.buffer_animations);
+ error = xwimp_update_window(&update, &more);
+ if (error) {
+ LOG(("xwimp_update_window: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ continue;
+ }
- plot = ro_plotters;
- ro_plot_origin_x = update.box.x0 - update.xscroll;
- ro_plot_origin_y = update.box.y1 - update.yscroll;
- ro_plot_set_scale(g->option.scale);
+ /* Set the current redraw gui_window to get options from
+ */
+ ro_gui_current_redraw_gui = g;
+ current_redraw_browser = g->bw;
- /* We should clear the background, except for HTML.
- */
- if (c->type != CONTENT_HTML)
- clear_background = true;
+ plot = ro_plotters;
+ ro_plot_origin_x = update.box.x0 - update.xscroll;
+ ro_plot_origin_y = update.box.y1 - update.yscroll;
+ ro_plot_set_scale(g->option.scale);
- while (more) {
- clip_x0 = (update.clip.x0 - ro_plot_origin_x) / 2;
- clip_y0 = (ro_plot_origin_y - update.clip.y1) / 2;
- clip_x1 = (update.clip.x1 - ro_plot_origin_x) / 2;
- clip_y1 = (ro_plot_origin_y - update.clip.y0) / 2;
-
- if (use_buffer)
- ro_gui_buffer_open(&update);
- if (data->redraw.full_redraw) {
- if (clear_background) {
- error = xcolourtrans_set_gcol(os_COLOUR_WHITE,
- colourtrans_SET_BG,
- os_ACTION_OVERWRITE, 0, 0);
- if (error) {
- LOG(("xcolourtrans_set_gcol: 0x%x: %s",
- error->errnum,
- error->errmess));
- warn_user("MiscError", error->errmess);
+ /* We should clear the background, except for HTML.
+ */
+ if (c->type != CONTENT_HTML)
+ clear_background = true;
+
+ while (more) {
+ clip_x0 = (update.clip.x0 - ro_plot_origin_x) / 2;
+ clip_y0 = (ro_plot_origin_y - update.clip.y1) / 2;
+ clip_x1 = (update.clip.x1 - ro_plot_origin_x) / 2;
+ clip_y1 = (ro_plot_origin_y - update.clip.y0) / 2;
+
+ if (use_buffer)
+ ro_gui_buffer_open(&update);
+ if (data->redraw.full_redraw) {
+ if (clear_background) {
+ error = xcolourtrans_set_gcol(os_COLOUR_WHITE,
+ colourtrans_SET_BG,
+ os_ACTION_OVERWRITE, 0, 0);
+ if (error) {
+ LOG(("xcolourtrans_set_gcol: 0x%x: %s",
+ error->errnum,
+ error->errmess));
+ warn_user("MiscError", error->errmess);
+ }
+ os_clg();
}
- os_clg();
- }
- content_redraw(c, 0, 0,
- c->width, c->height,
- clip_x0, clip_y0, clip_x1, clip_y1,
- g->option.scale,
- 0xFFFFFF);
- } else {
- assert(data->redraw.object);
- content_redraw(data->redraw.object,
- floorf(data->redraw.object_x *
- g->option.scale),
- ceilf(data->redraw.object_y *
- g->option.scale),
- data->redraw.object_width *
+ content_redraw(c, 0, 0,
+ c->width, c->height,
+ clip_x0, clip_y0, clip_x1, clip_y1,
g->option.scale,
- data->redraw.object_height *
+ 0xFFFFFF);
+ } else {
+ assert(data->redraw.object);
+ content_redraw(data->redraw.object,
+ floorf(data->redraw.object_x *
+ g->option.scale),
+ ceilf(data->redraw.object_y *
+ g->option.scale),
+ data->redraw.object_width *
+ g->option.scale,
+ data->redraw.object_height *
+ g->option.scale,
+ clip_x0, clip_y0, clip_x1, clip_y1,
g->option.scale,
- clip_x0, clip_y0, clip_x1, clip_y1,
- g->option.scale,
- 0xFFFFFF);
- }
+ 0xFFFFFF);
+ }
- if (use_buffer)
- ro_gui_buffer_close();
- error = xwimp_get_rectangle(&update, &more);
- /* RISC OS 3.7 returns an error here if enough buffer was
- claimed to cause a new dynamic area to be created. It
- doesn't actually stop anything working, so we mask it out
- for now until a better fix is found. This appears to be a
- bug in RISC OS. */
- if (error && !(use_buffer &&
- error->errnum == error_WIMP_GET_RECT)) {
- LOG(("xwimp_get_rectangle: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- ro_gui_current_redraw_gui = NULL;
- current_redraw_browser = NULL;
- return;
+ if (use_buffer)
+ ro_gui_buffer_close();
+ error = xwimp_get_rectangle(&update, &more);
+ /* RISC OS 3.7 returns an error here if enough buffer was
+ claimed to cause a new dynamic area to be created. It
+ doesn't actually stop anything working, so we mask it out
+ for now until a better fix is found. This appears to be a
+ bug in RISC OS. */
+ if (error && !(use_buffer &&
+ error->errnum == error_WIMP_GET_RECT)) {
+ LOG(("xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ ro_gui_current_redraw_gui = NULL;
+ current_redraw_browser = NULL;
+ continue;
+ }
}
+
+ /* Reset the current redraw gui_window to prevent thumbnails from
+ retaining options
+ */
+ ro_gui_current_redraw_gui = NULL;
+ current_redraw_browser = NULL;
+ }
+ while (pending_updates) {
+ cur = pending_updates;
+ pending_updates = pending_updates->next;
+ free(cur);
}
+
+}
+/**
+ * Redraw an area of a window.
+ *
+ * \param g gui_window
+ * \param data content_msg_data union with filled in redraw data
+ */
- /* Reset the current redraw gui_window to prevent thumbnails from
- retaining options
- */
- ro_gui_current_redraw_gui = NULL;
- current_redraw_browser = NULL;
+void gui_window_update_box(struct gui_window *g,
+ const union content_msg_data *data)
+{
+ struct content *c = g->bw->current_content;
+ bool use_buffer;
+ int x0, y0, x1, y1;
+ struct update_box *cur;
+
+ if (!c)
+ return;
+
+ x0 = floorf(data->redraw.x * 2 * g->option.scale);
+ y0 = -ceilf((data->redraw.y + data->redraw.height) * 2 * g->option.scale);
+ x1 = ceilf((data->redraw.x + data->redraw.width) * 2 * g->option.scale) + 1;
+ y1 = -floorf(data->redraw.y * 2 * g->option.scale) + 1;
+ use_buffer = (data->redraw.full_redraw) &&
+ (g->option.buffer_everything || g->option.buffer_animations);
+
+ /* try to optimise buffered redraws */
+ if (use_buffer) {
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ if ((cur->g != g) || (!cur->use_buffer))
+ continue;
+ if ((((cur->x0 - x1) < MARGIN) || ((cur->x1 - x0) < MARGIN)) &&
+ (((cur->y0 - y1) < MARGIN) || ((cur->y1 - y0) < MARGIN))) {
+ cur->x0 = min(cur->x0, x0);
+ cur->y0 = min(cur->y0, y0);
+ cur->x1 = max(cur->x1, x1);
+ cur->y1 = max(cur->y1, y1);
+ return;
+ }
+
+ }
+ }
+ cur = malloc(sizeof(struct update_box));
+ if (!cur) {
+ LOG(("No memory for malloc."));
+ warn_user("NoMemory", 0);
+ return;
+ }
+ cur->x0 = x0;
+ cur->y0 = y0;
+ cur->x1 = x1;
+ cur->y1 = y1;
+ cur->next = pending_updates;
+ pending_updates = cur;
+ cur->g = g;
+ cur->use_buffer = use_buffer;
+ cur->data = *data;
}