Hi I wrote this ages ago but failed to do anything further with it. I've just cleaned it up and checked it still builds.
It stops GIF animations when they are no longer being used, rather than waiting for them to be destroyed. This prevents NetSurf from wasting time cycling through frames when there is nothing to see. Chris
diff --git a/content/content.c b/content/content.c index d5eff46..3438239 100644 --- a/content/content.c +++ b/content/content.c @@ -670,6 +670,9 @@ bool content_add_user(struct content *c, user->next = c->user_list->next; c->user_list->next = user; + if (c->handler->add_user != NULL) + c->handler->add_user(c); + return true; } @@ -699,6 +702,10 @@ void content_remove_user(struct content *c, assert(0); return; } + + if (c->handler->remove_user != NULL) + c->handler->remove_user(c); + next = user->next; user->next = next->next; free(next); diff --git a/content/content_protected.h b/content/content_protected.h index 7311da6..e5ff1ca 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -82,6 +82,8 @@ struct content_handler { bool (*matches_quirks)(const struct content *c, bool quirks); const char *(*get_encoding)(const struct content *c, enum content_encoding_type op); content_type (*type)(void); + void (*add_user)(struct content *c); + void (*remove_user)(struct content *c); /** handler dependant content sensitive internal data interface. */ void * (*get_internal)(const struct content *c, void *context); diff --git a/image/gif.c b/image/gif.c index 3f5f630..fb0985a 100644 --- a/image/gif.c +++ b/image/gif.c @@ -392,6 +392,31 @@ static nserror nsgif_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void nsgif_add_user(struct content *c) +{ + nsgif_content *gif = (nsgif_content *) c; + + /* Ensure this content has already been converted. + * If it hasn't, the animation will start at the conversion phase instead. */ + if (gif->gif == NULL) return; + + if (content_count_users(c) == 1) { + /* First user, and content already converted, so start the animation. */ + if (gif->gif->frame_count_partial > 1) { + guit->browser->schedule(gif->gif->frames[0].frame_delay * 10, + nsgif_animate, c); + } + } +} + +static void nsgif_remove_user(struct content *c) +{ + if (content_count_users(c) == 1) { + /* Last user is about to be removed from this content, so stop the animation. */ + guit->browser->schedule(-1, nsgif_animate, c); + } +} + static void *nsgif_get_internal(const struct content *c, void *context) { nsgif_content *gif = (nsgif_content *) c; @@ -415,6 +440,8 @@ static const content_handler nsgif_content_handler = { .destroy = nsgif_destroy, .redraw = nsgif_redraw, .clone = nsgif_clone, + .add_user = nsgif_add_user, + .remove_user = nsgif_remove_user, .get_internal = nsgif_get_internal, .type = nsgif_content_type, .no_share = false,