From d18f4397c7906880facdf7dc533d663e086771e6 Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Mon, 19 Jul 2004 23:35:12 +0000 Subject: [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 --- !NetSurf/Docs/about,faf | 2 +- makefile | 2 +- riscos/buffer.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ riscos/buffer.h | 20 ++++++ riscos/options.h | 7 +- riscos/window.c | 3 + 6 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 riscos/buffer.c create mode 100644 riscos/buffer.h diff --git a/!NetSurf/Docs/about,faf b/!NetSurf/Docs/about,faf index 2a86fb8eb..70d0b2a81 100644 --- a/!NetSurf/Docs/about,faf +++ b/!NetSurf/Docs/about,faf @@ -9,7 +9,7 @@ -

NetSurf VERSION

+

NetSurf Test Build (16 Jul 2004 21:00)

Authors and contributors: (code) John M Bell, James Bursa, Matthew Hambley, Rob Jackson, diff --git a/makefile b/makefile index 10cf54482..b8447db69 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ OBJECTS_COMMON += imagemap.o loginlist.o options.o # desktop/ OBJECTS_RISCOS = $(OBJECTS_COMMON) OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/ OBJECTS_RISCOS += 401login.o debugwin.o \ - dialog.o download.o draw.o filetype.o font.o gif.o \ + buffer.o dialog.o download.o draw.o filetype.o font.o gif.o \ gifread.o gui.o help.o history.o hotlist.o htmlinstance.o \ htmlredraw.o jpeg.o menus.o mng.o mouseactions.o plugin.o \ png.o save.o save_complete.o save_draw.o save_text.o \ 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 + */ + +#include +#include +#include +#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 + */ + +/** \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); -- cgit v1.2.3