summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2004-07-19 23:35:12 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2004-07-19 23:35:12 +0000
commitd18f4397c7906880facdf7dc533d663e086771e6 (patch)
tree0677d7be5b57a18192f4ac8c5560ebf7419644b1 /riscos
parent2fedec98f917f221e228f71df62670a8e43c4d6a (diff)
downloadnetsurf-d18f4397c7906880facdf7dc533d663e086771e6.tar.gz
netsurf-d18f4397c7906880facdf7dc533d663e086771e6.tar.bz2
[project @ 2004-07-19 23:35:12 by rjw]
Double buffering for animations to remove flicker. Background font blending turned on by default. svn path=/import/netsurf/; revision=1121
Diffstat (limited to 'riscos')
-rw-r--r--riscos/buffer.c168
-rw-r--r--riscos/buffer.h20
-rw-r--r--riscos/options.h7
-rw-r--r--riscos/window.c3
4 files changed, 196 insertions, 2 deletions
diff --git a/riscos/buffer.c b/riscos/buffer.c
new file mode 100644
index 000000000..bc3c2cc72
--- /dev/null
+++ b/riscos/buffer.c
@@ -0,0 +1,168 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "oslib/colourtrans.h"
+#include "oslib/os.h"
+#include "oslib/osspriteop.h"
+#include "oslib/wimp.h"
+#include "netsurf/riscos/buffer.h"
+#include "netsurf/riscos/wimp.h"
+#include "netsurf/utils/log.h"
+
+/* SCREEN BUFFERING
+ ================
+
+ Because RISC OS provides no native way for windows to be buffered (ie
+ the contents is only updated when the task has finished doing any
+ drawing) certain situation cause the window contents to flicker in an
+ undesirable manner. Examples of this are GIF and MNG animations, and
+ web pages with fixed backgrounds.
+
+ To overcome this, a very simple, transparent, interface is provided here
+ to allow for output to be buffered. It should be noted that screen
+ buffering can lower the perceived client response time as the user is
+ unable to see that the application is doing anything.
+
+ [rjw] - Mon 19th July 2004
+*/
+
+
+/** The current buffer
+*/
+static osspriteop_area *buffer = NULL;
+
+/** The current clip area
+*/
+static os_box clipping;
+
+/** The current save area
+*/
+static osspriteop_save_area *save_area;
+static osspriteop_area *context1;
+static osspriteop_id context2;
+static osspriteop_save_area *context3;
+
+
+/**
+ * Opens a buffer for writing to.
+ *
+ * \param redraw the current WIMP redraw area to buffer
+ */
+void ro_gui_buffer_open(wimp_draw *redraw) {
+ int size;
+ int orig_x0, orig_y0;
+ int buffer_size;
+ os_coord sprite_size;
+ os_error *error;
+
+ /* Close any open buffer
+ */
+ if (buffer) ro_gui_buffer_close();
+
+ /* Store our clipping region
+ */
+ clipping = redraw->clip;
+
+ /* Work out how much buffer we need
+ */
+ sprite_size.x = clipping.x1 - clipping.x0 + 1;
+ sprite_size.y = clipping.y1 - clipping.y0 + 1;
+ ro_convert_os_units_to_pixels(&sprite_size, (os_mode)-1);
+
+ /* Create our buffer (assume 32bpp for now (!))
+ */
+ buffer_size = sizeof(osspriteop_area) + sizeof(osspriteop_header) +
+ (sprite_size.x * sprite_size.y * 4) + 2048;
+ if (!(buffer = (osspriteop_area *)malloc(buffer_size))) return;
+
+ /* Fill in the sprite area details
+ */
+ buffer->size = buffer_size;
+ buffer->sprite_count = 0;
+ buffer->first = 16;
+ buffer->used = 16;
+
+ /* Fill in the sprite header details
+ */
+ if (xosspriteop_get_sprite_user_coords(osspriteop_NAME, buffer,
+ "buffer", (osbool)1,
+ clipping.x0, clipping.y0, clipping.x1, clipping.y1)) {
+ free(buffer);
+ buffer = NULL;
+ return;
+ }
+
+ /* Allocate OS_SpriteOp save area
+ */
+ if ((error = xosspriteop_read_save_area_size(osspriteop_NAME, buffer,
+ (osspriteop_id)"buffer", &size))) {
+ LOG(("Save error: %s", error->errmess));
+ free(buffer);
+ buffer = NULL;
+ return;
+ }
+ if (!(save_area = malloc((unsigned)size))) {
+ free(buffer);
+ buffer = NULL;
+ return;
+ }
+ save_area->a[0] = 0;
+
+ /* Switch output to sprite
+ */
+ if ((error = xosspriteop_switch_output_to_sprite(osspriteop_NAME, buffer,
+ (osspriteop_id)"buffer", save_area,
+ 0, (int *)&context1, (int *)&context2, (int *)&context3))) {
+ LOG(("Switching error: %s", error->errmess));
+ free(save_area);
+ free(buffer);
+ buffer = NULL;
+ return;
+ }
+
+ /* Move the origin such that (x0, y0) becomes (0, 0). To do this
+ we use VDU 29,(1 << 16) - x0; (1 << 16) - y0; because RISC OS
+ is so insanely legacy driven.
+ */
+ orig_x0 = (1 << 16) - clipping.x0;
+ orig_y0 = (1 << 16) - clipping.y0;
+ os_writec((char)29);
+ os_writec(orig_x0 & 0xff); os_writec(orig_x0 >> 8);
+ os_writec(orig_y0 & 0xff); os_writec(orig_y0 >> 8);
+}
+
+
+/**
+ * Closes any open buffer and flushes the contents to screen
+ */
+void ro_gui_buffer_close(void) {
+
+ /* Check we have an open buffer
+ */
+ if (!buffer) return;
+
+ /* Remove any redirection and origin hacking
+ */
+ xosspriteop_switch_output_to_sprite(osspriteop_PTR,
+ context1, context2, context3,
+ 0, 0, 0, 0);
+ free(save_area);
+
+ /* Plot the contents to screen
+ */
+ xosspriteop_put_sprite_user_coords(osspriteop_NAME,
+ buffer, (osspriteop_id)"buffer",
+ clipping.x0, clipping.y0, (os_action)0);
+
+ /* Free our memory
+ */
+ free(buffer);
+ buffer = NULL;
+}
diff --git a/riscos/buffer.h b/riscos/buffer.h
new file mode 100644
index 000000000..8340dd24f
--- /dev/null
+++ b/riscos/buffer.h
@@ -0,0 +1,20 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
+ */
+
+/** \file
+ * Screen buffering (interface).
+ */
+
+#ifndef _NETSURF_RISCOS_BUFFER_H_
+#define _NETSURF_RISCOS_BUFFER_H_
+
+#include "oslib/wimp.h"
+
+void ro_gui_buffer_open(wimp_draw *redraw);
+void ro_gui_buffer_close(void);
+
+#endif
diff --git a/riscos/options.h b/riscos/options.h
index 5c9392038..be1769d15 100644
--- a/riscos/options.h
+++ b/riscos/options.h
@@ -43,6 +43,7 @@ extern bool option_window_size_clone;
extern int option_minimum_gif_delay;
extern bool option_background_images;
extern bool option_background_blending;
+extern bool option_buffer_animations;
#define EXTRA_OPTION_DEFINE \
bool option_use_mouse_gestures = false;\
@@ -71,7 +72,8 @@ bool option_window_stagger = true; \
bool option_window_size_clone = true; \
int option_minimum_gif_delay = 10; \
bool option_background_images = true; \
-bool option_background_blending = false;
+bool option_background_blending = true; \
+bool option_buffer_animations = true;
#define EXTRA_OPTION_TABLE \
{ "use_mouse_gestures", OPTION_BOOL, &option_use_mouse_gestures },\
@@ -100,6 +102,7 @@ bool option_background_blending = false;
{ "window_size_clone", OPTION_BOOL, &option_window_size_clone }, \
{ "minimum_gif_delay", OPTION_INTEGER, &option_minimum_gif_delay }, \
{ "background_images", OPTION_BOOL, &option_background_images }, \
-{ "background_blending", OPTION_BOOL, &option_background_blending }
+{ "background_blending", OPTION_BOOL, &option_background_blending }, \
+{ "buffer_animations", OPTION_BOOL, &option_buffer_animations }
#endif
diff --git a/riscos/window.c b/riscos/window.c
index b5981ec58..76a5e267c 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -23,6 +23,7 @@
#include "oslib/wimpspriteop.h"
#include "netsurf/css/css.h"
#include "netsurf/utils/config.h"
+#include "netsurf/riscos/buffer.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/options.h"
#include "netsurf/riscos/theme.h"
@@ -493,6 +494,7 @@ void gui_window_update_box(struct gui_window *g,
while (more) {
if (data->redraw.full_redraw) {
+ if (option_buffer_animations) ro_gui_buffer_open(&update);
if (clear_background) {
error = xcolourtrans_set_gcol(os_COLOUR_WHITE,
colourtrans_SET_BG,
@@ -513,6 +515,7 @@ void gui_window_update_box(struct gui_window *g,
update.clip.x0, update.clip.y0,
update.clip.x1 - 1, update.clip.y1 - 1,
g->option.scale);
+ if (option_buffer_animations) ro_gui_buffer_close();
} else {
assert(data->redraw.object);