From fb1266c98b409e0ff9a2c6bb2422879132b3922d Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 28 Aug 2014 17:35:50 +0200 Subject: player: update cache state only if requested Add a mechanism to the client API code, which allows the player core to query whether a client API event is needed at all. Use it for the cache update. In this case, this is probably a pure microoptimization; but the mechanism will be useful for other things too. --- player/client.c | 38 +++++++++++++++++++++++++++++++++++++- player/client.h | 1 + player/playloop.c | 7 ++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/player/client.c b/player/client.c index 0897534a15..411d634100 100644 --- a/player/client.c +++ b/player/client.c @@ -59,6 +59,7 @@ struct mp_client_api { // -- protected by lock struct mpv_handle **clients; int num_clients; + uint64_t event_masks; // combined events of all clients, or 0 if unknown }; struct observe_property { @@ -150,6 +151,13 @@ int mp_clients_num(struct MPContext *mpctx) return num_clients; } +static void invalidate_global_event_mask(struct mpv_handle *ctx) +{ + pthread_mutex_lock(&ctx->clients->lock); + ctx->clients->event_masks = 0; + pthread_mutex_unlock(&ctx->clients->lock); +} + static struct mpv_handle *find_client(struct mp_client_api *clients, const char *name) { @@ -199,12 +207,14 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name pthread_mutex_init(&client->wakeup_lock, NULL); pthread_cond_init(&client->wakeup, NULL); - mpv_request_event(client, MPV_EVENT_TICK, 0); MP_TARRAY_APPEND(clients, clients->clients, clients->num_clients, client); + clients->event_masks = 0; pthread_mutex_unlock(&clients->lock); + mpv_request_event(client, MPV_EVENT_TICK, 0); + return client; } @@ -502,6 +512,29 @@ static void dup_event_data(struct mpv_event *ev) } } +// Return whether there's any client listening to this event. +// If false is returned, the core doesn't need to send it. +bool mp_client_event_is_registered(struct MPContext *mpctx, int event) +{ + struct mp_client_api *clients = mpctx->clients; + + pthread_mutex_lock(&clients->lock); + + if (!clients->event_masks) { // lazy update + for (int n = 0; n < clients->num_clients; n++) { + struct mpv_handle *ctx = clients->clients[n]; + pthread_mutex_lock(&ctx->lock); + clients->event_masks |= ctx->event_mask | ctx->property_event_masks; + pthread_mutex_unlock(&ctx->lock); + } + } + bool r = clients->event_masks & (1ULL << event); + + pthread_mutex_unlock(&clients->lock); + + return r; +} + void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data) { struct mp_client_api *clients = mpctx->clients; @@ -555,6 +588,7 @@ int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable) uint64_t bit = 1ULL << event; ctx->event_mask = enable ? ctx->event_mask | bit : ctx->event_mask & ~bit; pthread_mutex_unlock(&ctx->lock); + invalidate_global_event_mask(ctx); return 0; } @@ -1140,6 +1174,7 @@ int mpv_observe_property(mpv_handle *ctx, uint64_t userdata, ctx->property_event_masks |= prop->event_mask; ctx->lowest_changed = 0; pthread_mutex_unlock(&ctx->lock); + invalidate_global_event_mask(ctx); return 0; } @@ -1168,6 +1203,7 @@ int mpv_unobserve_property(mpv_handle *ctx, uint64_t userdata) } ctx->lowest_changed = 0; pthread_mutex_unlock(&ctx->lock); + invalidate_global_event_mask(ctx); return count; } diff --git a/player/client.h b/player/client.h index b329ae6d7b..a8804dbf82 100644 --- a/player/client.h +++ b/player/client.h @@ -17,6 +17,7 @@ int mp_clients_num(struct MPContext *mpctx); void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data); int mp_client_send_event(struct MPContext *mpctx, const char *client_name, int event, void *data); +bool mp_client_event_is_registered(struct MPContext *mpctx, int event); void mp_client_property_change(struct MPContext *mpctx, const char *name); struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name); diff --git a/player/playloop.c b/player/playloop.c index dcbda59f13..4aaeacff16 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -49,6 +49,7 @@ #include "video/out/vo.h" #include "core.h" +#include "client.h" #include "command.h" void pause_player(struct MPContext *mpctx) @@ -556,7 +557,11 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx) } // Also update cache properties. - bool busy = idle == 0 || !s.idle; + bool busy = idle == 0; + if (!s.idle) { + busy |= idle != -1; + busy |= mp_client_event_is_registered(mpctx, MP_EVENT_CACHE_UPDATE); + } if (busy || mpctx->next_cache_update > 0) { double now = mp_time_sec(); if (mpctx->next_cache_update <= now) { -- cgit v1.2.3