From 92743be24d5ccc99de21dee81ee36307b94877a7 Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Tue, 5 Apr 2005 02:36:33 +0000 Subject: [project @ 2005-04-05 02:36:33 by rjw] Reduce re-allocation of memory when receiving files (drastically increases the speed of loading large files locally). Sprite files no longer require two copies of their data. svn path=/import/netsurf/; revision=1598 --- content/content.c | 40 +++++++++++++++++++++++++++++----------- content/content.h | 1 + riscos/sprite.c | 42 ++++++++---------------------------------- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/content/content.c b/content/content.c index 9e113cac0..b80d5de89 100644 --- a/content/content.c +++ b/content/content.c @@ -195,7 +195,7 @@ static const struct handler_entry handler_map[] = { 0, nsmng_destroy, 0, nsmng_redraw, 0, 0, false}, #endif #ifdef WITH_SPRITE - {sprite_create, sprite_process_data, sprite_convert, + {sprite_create, 0, sprite_convert, 0, sprite_destroy, 0, sprite_redraw, 0, 0, false}, #endif #ifdef WITH_DRAW @@ -290,6 +290,7 @@ struct content * content_create(const char *url) c->fetch = 0; c->source_data = 0; c->source_size = 0; + c->source_allocated = 0; c->total_size = 0; c->no_error_pages = false; c->download = false; @@ -475,29 +476,36 @@ bool content_process_data(struct content *c, const char *data, { char *source_data; union content_msg_data msg_data; + unsigned int extra_space; assert(c); assert(c->type < HANDLER_MAP_COUNT); assert(c->status == CONTENT_STATUS_LOADING); LOG(("content %s, size %u", c->url, size)); - source_data = talloc_realloc(c, c->source_data, char, - c->source_size + size); - if (!source_data) { - c->status = CONTENT_STATUS_ERROR; - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - warn_user("NoMemory", 0); - return false; + if ((c->source_size + size) > c->source_allocated) { + extra_space = (c->source_size + size) / 4; + if (extra_space < 65536) + extra_space = 65536; + source_data = talloc_realloc(c, c->source_data, char, + c->source_size + size + extra_space); + if (!source_data) { + c->status = CONTENT_STATUS_ERROR; + msg_data.error = messages_get("NoMemory"); + content_broadcast(c, CONTENT_MSG_ERROR, msg_data); + warn_user("NoMemory", 0); + return false; + } + c->source_data = source_data; + c->source_allocated = c->source_size + size + extra_space; } - c->source_data = source_data; memcpy(c->source_data + c->source_size, data, size); c->source_size += size; c->size += size; if (handler_map[c->type].process_data) { if (!handler_map[c->type].process_data(c, - source_data + c->source_size - size, size)) { + c->source_data + c->source_size - size, size)) { c->status = CONTENT_STATUS_ERROR; return false; } @@ -523,12 +531,22 @@ bool content_process_data(struct content *c, const char *data, void content_convert(struct content *c, int width, int height) { union content_msg_data msg_data; + char *source_data; assert(c); assert(c->type < HANDLER_MAP_COUNT); assert(c->status == CONTENT_STATUS_LOADING); LOG(("content %s", c->url)); + if (c->source_allocated != c->source_size) { + source_data = talloc_realloc(c, c->source_data, char, + c->source_size); + if (source_data) { + c->source_data = source_data; + c->source_allocated = c->source_size; + } + } + c->available_width = width; if (handler_map[c->type].convert) { if (!handler_map[c->type].convert(c, width, height)) { diff --git a/content/content.h b/content/content.h index 387fc7a37..0c6833e67 100644 --- a/content/content.h +++ b/content/content.h @@ -239,6 +239,7 @@ struct content { struct fetch *fetch; /**< Associated fetch, or 0. */ char *source_data; /**< Source data, as received. */ unsigned long source_size; /**< Amount of data fetched so far. */ + unsigned long source_allocated; /**< Amount of space allocated so far. */ unsigned long total_size; /**< Total data size, 0 if unknown. */ bool no_error_pages; /**< Used by fetchcache(). */ diff --git a/riscos/sprite.c b/riscos/sprite.c index a68cd57ce..837dedfbe 100644 --- a/riscos/sprite.c +++ b/riscos/sprite.c @@ -52,34 +52,6 @@ bool sprite_create(struct content *c, const char *params[]) } -/** - * Process data for a CONTENT_SPRITE. - * - * The data is just copied into the sprite area. - */ - -bool sprite_process_data(struct content *c, char *data, unsigned int size) -{ - char *sprite_data; - union content_msg_data msg_data; - - sprite_data = realloc(c->data.sprite.data, - c->data.sprite.length + size); - if (!sprite_data) { - msg_data.error = messages_get("NoMemory"); - content_broadcast(c, CONTENT_MSG_ERROR, msg_data); - warn_user("NoMemory", 0); - return false; - } - c->data.sprite.data = sprite_data; - memcpy((char*)(c->data.sprite.data) + c->data.sprite.length, - data, size); - c->data.sprite.length += size; - c->size += size; - return true; -} - - /** * Convert a CONTENT_SPRITE for display. * @@ -91,13 +63,14 @@ bool sprite_convert(struct content *c, int width, int height) os_error *error; int w, h; union content_msg_data msg_data; - osspriteop_area *area = (osspriteop_area*)c->data.sprite.data; - - /* fill in the size (first word) of the area */ - area->size = c->data.sprite.length; + char *source_data; + + source_data = ((char *)c->source_data) - 4; + osspriteop_area *area = (osspriteop_area*)source_data; + c->data.sprite.data = area; error = xosspriteop_read_sprite_info(osspriteop_PTR, - area, + (osspriteop_area *)0x100, (osspriteop_id) ((char *) area + area->first), &w, &h, NULL, NULL); if (error) { @@ -125,7 +98,8 @@ bool sprite_convert(struct content *c, int width, int height) void sprite_destroy(struct content *c) { - free(c->data.sprite.data); + /* do not free c->data.sprite.data at it is simply a pointer to + * 4 bytes before the c->data.source_data. */ free(c->title); } -- cgit v1.2.3