summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-08-28 17:35:50 +0200
committerwm4 <wm4@nowhere>2014-08-28 17:49:09 +0200
commitfb1266c98b409e0ff9a2c6bb2422879132b3922d (patch)
tree32b39734b2daf8750ee94d762f3c01b35f3735d5
parentf9f436a49093bed07e9a14ad2c7b974bb7e32f36 (diff)
downloadmpv-fb1266c98b409e0ff9a2c6bb2422879132b3922d.tar.bz2
mpv-fb1266c98b409e0ff9a2c6bb2422879132b3922d.tar.xz
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.
-rw-r--r--player/client.c38
-rw-r--r--player/client.h1
-rw-r--r--player/playloop.c7
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) {