src/bin/server/e_tizen_clipboard.c \
src/bin/server/e_surface_view.c \
src/bin/server/e_seat.c \
+src/bin/server/e_surface_fps_tracker.c \
src/bin/windowmgr/services/e_service_gesture.c \
src/bin/windowmgr/services/e_service_lockscreen.c \
src/bin/windowmgr/services/e_service_quickpanel.c \
#include "e_view_client_intern.h"
#include "e_blur_intern.h"
#include "e_blur_video_capture_intern.h"
+#include "e_compositor_intern.h"
+#include "e_surface_fps_tracker_intern.h"
#include <tbm_bufmgr.h>
#include <tbm_debug.h>
return reply;
}
-static E_Client *
-_e_info_server_find_client_by_win_id(uint64_t win_id)
-{
- Ecore_Window win;
- Evas_Object *o;
- E_Client *ec;
-
- for (o = evas_object_top_get(e_comp_evas_get()); o; o = evas_object_below_get(o))
- {
- ec = evas_object_data_get(o, "E_Client");
- if (!ec) continue;
-
- win = e_client_util_win_get(ec);
- if (win == win_id)
- return ec;
- }
-
- return NULL;
-}
-
static void
-_msg_client_fps_append(Eldbus_Message_Iter *iter, E_Client *ec)
+_msg_client_fps_append(Eldbus_Message_Iter *iter, E_Surface_Fps_Tracker *tracker, struct wl_resource *surface_resource)
{
Eldbus_Message_Iter *array_of_fps, *struct_of_fps;
double fps = 0.0;
eldbus_message_iter_arguments_append(iter, "a("VALUE_TYPE_FOR_FPS")", &array_of_fps);
- if (e_client_fps_get(ec, &fps))
+ if (e_surface_fps_tracker_fps_get(tracker, &fps))
{
eldbus_message_iter_arguments_append(array_of_fps, "("VALUE_TYPE_FOR_FPS")", &struct_of_fps);
eldbus_message_iter_arguments_append(struct_of_fps,
E_INFO_FPS_TYPE_CLIENT_WIN,
"none",
-999,
- e_client_util_win_get(ec),
+ surface_resource,
fps);
eldbus_message_iter_container_close(array_of_fps, struct_of_fps);
}
_e_info_server_cb_fps_info_get(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
{
const char *win_str;
- uint64_t win_id = 0;
- unsigned long tmp;
- E_Client *ec;
+ struct wl_resource *surface_resource;
+ unsigned long surface_resource_ptr;
+ E_Surface *surface;
+ E_Surface_Fps_Tracker *tracker;
Eldbus_Message *reply = eldbus_message_method_return_new(msg);
if (!eldbus_message_arguments_get(msg, "s", &win_str))
if (e_util_strcmp(win_str, "none"))
{
- if (!e_util_string_to_ulong(win_str, &tmp, 16))
+ if (!e_util_string_to_ulong(win_str, &surface_resource_ptr, 16))
return reply;
- win_id = (uint64_t)tmp;
-
- ec = _e_info_server_find_client_by_win_id(win_id);
- if (!ec) return reply;
-
- e_client_fps_enable(ec, EINA_TRUE);
- _msg_client_fps_append(eldbus_message_iter_get(reply), ec);
+ surface_resource = (struct wl_resource *)surface_resource_ptr;
+ surface = e_compositor_surface_find_by_resource(surface_resource);
+ if (surface)
+ {
+ tracker = e_surface_fps_tracker_get_or_create(surface);
+ _msg_client_fps_append(eldbus_message_iter_get(reply), tracker, surface_resource);
+ }
}
else
{
--- /dev/null
+#include "e_surface_fps_tracker_intern.h"
+#include "e_compositor_private.h"
+
+#include <stdlib.h>
+#include <wayland-util.h>
+
+struct _E_Surface_Fps_Tracker
+{
+ double fps;
+ double old_fps;
+ double frametime;
+ double time;
+ double lapse;
+ int cframes;
+ int flapse;
+
+ struct wl_listener surface_destroy;
+ struct wl_listener commit;
+};
+
+static void
+_tracker_cb_surface_destroy(struct wl_listener *listener, void *data)
+{
+ E_Surface_Fps_Tracker *tracker = wl_container_of(listener, tracker, surface_destroy);
+
+ wl_list_remove(&tracker->surface_destroy.link);
+ wl_list_remove(&tracker->commit.link);
+ free(tracker);
+}
+
+static E_Surface_Fps_Tracker *
+_tracker_try_from_surface(E_Surface *surface)
+{
+ E_Surface_Fps_Tracker *tracker;
+ struct wl_listener *listener;
+
+ listener = e_surface_destroy_listener_get(surface, _tracker_cb_surface_destroy);
+ if (!listener)
+ return NULL;
+
+ return wl_container_of(listener, tracker, surface_destroy);
+}
+
+static void
+_tracker_fps_update(E_Surface_Fps_Tracker *tracker)
+{
+ double dt;
+ double tim;
+
+ tim = ecore_time_get();
+
+ dt = tim - tracker->frametime;
+
+ tracker->frametime = tim;
+ tracker->time += dt;
+ tracker->cframes++;
+
+ if (tracker->lapse == 0.0)
+ {
+ tracker->lapse = tim;
+ tracker->flapse = tracker->cframes;
+ }
+ else if ((tim - tracker->lapse) >= 0.5)
+ {
+ tracker->fps = (tracker->cframes - tracker->flapse) /
+ (tim - tracker->lapse);
+ tracker->lapse = tim;
+ tracker->flapse = tracker->cframes;
+ tracker->time = 0.0;
+ }
+}
+
+static void
+_tracker_cb_commit(struct wl_listener *listener, void *data)
+{
+ E_Surface_Fps_Tracker *tracker = wl_container_of(listener, tracker, commit);
+ E_Surface_Event_Commit *event = data;
+
+ if (event->committed & E_SURFACE_STATE_BUFFER)
+ _tracker_fps_update(tracker);
+}
+
+static E_Surface_Fps_Tracker *
+_tracker_create(E_Surface *surface)
+{
+ E_Surface_Fps_Tracker *tracker;
+
+ tracker = calloc(1, sizeof(*tracker));
+ if (!tracker)
+ return NULL;
+
+ tracker->surface_destroy.notify = _tracker_cb_surface_destroy;
+ e_surface_destroy_listener_add(surface, &tracker->surface_destroy);
+
+ tracker->commit.notify = _tracker_cb_commit;
+ e_surface_commit_listener_add(surface, &tracker->commit);
+
+ return tracker;
+}
+
+EINTERN E_Surface_Fps_Tracker *
+e_surface_fps_tracker_get_or_create(E_Surface *surface)
+{
+ E_Surface_Fps_Tracker *tracker;
+
+ tracker = _tracker_try_from_surface(surface);
+ if (tracker)
+ return tracker;
+
+ return _tracker_create(surface);
+}
+
+EINTERN Eina_Bool
+e_surface_fps_tracker_fps_get(E_Surface_Fps_Tracker *tracker, double *fps)
+{
+ if (tracker->old_fps == tracker->fps)
+ return EINA_FALSE;
+
+ if (tracker->fps > 0.0)
+ {
+ *fps = tracker->fps;
+ tracker->old_fps = tracker->fps;
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
--- /dev/null
+#ifndef E_SURFACE_FPS_TRACKER_INTERN_H
+#define E_SURFACE_FPS_TRACKER_INTERN_H
+
+#include <wayland-server.h>
+#include <Eina.h>
+
+#include "e_compositor_intern.h"
+
+typedef struct _E_Surface_Fps_Tracker E_Surface_Fps_Tracker;
+
+/**
+ * Creates or retrieves an existing E_Surface_Fps_Tracker instance associated
+ * with the given surface.
+ */
+E_Surface_Fps_Tracker *e_surface_fps_tracker_get_or_create(E_Surface *surface);
+
+/**
+ * Gets the most recently calculated FPS value.
+ *
+ * The FPS value is calculated based on the time an associated surface submits
+ * new buffer and commits it.
+ */
+Eina_Bool e_surface_fps_tracker_fps_get(E_Surface_Fps_Tracker *tracker, double *fps);
+
+#endif