#include "e_comp_wl_subsurface_intern.h"
#include "e_comp_intern.h"
#include "e_pixmap_intern.h"
-#include "e_presentation_time_intern.h"
#include "e_client_video_intern.h"
#include "e_client_intern.h"
#include "e_view_client_intern.h"
#include <libds/types/ds_surface.h>
#include <libds/types/ds_subsurface.h>
#include <libds-tizen/surface_exporter.h>
+#include <wayland-server-core.h>
typedef struct _E_Subsurface E_Subsurface;
typedef struct _E_Subsurface_View E_Subsurface_View;
struct wl_listener new_exported_surface;
};
+typedef enum
+{
+ E_SURFACE_STATE_CLEAN = 0,
+ E_SURFACE_STATE_PRESENTATION_TIME_FEEDBACK = 1 << 0,
+} E_Surface_State_Field;
+
+typedef struct
+{
+ E_Surface_State_Field committed;
+ E_Presentation_Time_Container presentation_container;
+} E_Surface_State;
+
struct _E_Surface
{
E_Comp_Wl_Client_Data base;
const char *role_name;
struct wl_list frames;
+ E_Surface_State pending, current;
+
struct wl_listener destroy;
struct wl_listener precommit_to_cache;
struct wl_listener precommit_from_cache;
E_Surface *parent;
struct ds_subsurface *ds_subsurface;
- struct
- {
- E_Presentation_Time_Container presentation_container;
- Eina_Bool has_data;
- } cached;
+ E_Surface_State cached;
struct wl_listener destroy;
struct wl_listener surface_destroy;
return ds_surface_get_wl_resource(surface->ds_surface);
}
+EINTERN void
+e_surface_presentation_time_feedback_add(E_Surface *surface, E_Presentation_Time_Feedback *feedback)
+{
+ e_presentation_time_container_feedback_set(&surface->pending.presentation_container, feedback);
+ surface->pending.committed |= E_SURFACE_STATE_PRESENTATION_TIME_FEEDBACK;
+}
+
EINTERN E_Subsurface *
e_subsurface_try_from_surface(E_Surface *surface)
{
surface->base.sub.list_changed |= reordered;
}
+static void
+_e_surface_pending_presentation_time_feedback_update(E_Surface *surface)
+{
+ e_presentation_time_container_feedback_discard(&surface->base.presentation_container);
+ e_presentation_time_container_feedback_merge(&surface->base.presentation_container, &surface->current.presentation_container);
+}
+
static void
_e_surface_pending_update(E_Surface *surface)
{
E_Surface *root_surface;
struct ds_surface *ds_surface = surface->ds_surface;
+ if (surface->current.committed & E_SURFACE_STATE_PRESENTATION_TIME_FEEDBACK)
+ _e_surface_pending_presentation_time_feedback_update(surface);
+
if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER)
_e_surface_pending_buffer_update(surface);
e_comp_wl_client_surface_finish(surface->ec);
}
+static void
+_e_surface_state_move(E_Surface_State *dst, E_Surface_State *src)
+{
+ if (src->committed & E_SURFACE_STATE_PRESENTATION_TIME_FEEDBACK)
+ {
+ e_presentation_time_container_feedback_discard(&dst->presentation_container);
+ e_presentation_time_container_feedback_merge(&dst->presentation_container, &src->presentation_container);
+ }
+
+ dst->committed |= src->committed;
+ src->committed = E_SURFACE_STATE_CLEAN;
+}
+
static void
_e_surface_cb_precommit_to_cache(struct wl_listener *listener, void *data)
{
wl_signal_emit(&surface->events.precommit_to_cache, surface);
- e_presentation_time_container_feedback_discard(&subsurface->cached.presentation_container);
- e_presentation_time_container_feedback_merge(&subsurface->cached.presentation_container,
- &surface->base.pending.presentation_container);
-
- subsurface->cached.has_data = EINA_TRUE;
+ _e_surface_state_move(&subsurface->cached, &surface->pending);
e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_COMMIT_TO_CACHE, surface->ec);
}
wl_signal_emit(&surface->events.precommit_from_cache, surface);
- if (subsurface->cached.has_data)
- {
- e_presentation_time_container_feedback_discard(&surface->base.presentation_container);
- e_presentation_time_container_feedback_merge(&surface->base.presentation_container,
- &subsurface->cached.presentation_container);
- subsurface->cached.has_data = EINA_FALSE;
- }
+ _e_surface_state_move(&surface->current, &subsurface->cached);
// The _e_subsurface_synchronized_check() should be called, because this
// callback could be called due to the wl_subsurface.set_desync()
wl_signal_emit(&surface->events.precommit_from_pending, surface);
- e_presentation_time_container_feedback_discard(&surface->base.presentation_container);
- e_presentation_time_container_feedback_merge(&surface->base.presentation_container,
- &surface->base.pending.presentation_container);
+ _e_surface_state_move(&surface->current, &surface->pending);
}
static void
_e_surface_commit(surface);
wl_signal_emit(&surface->events.commit, surface);
+ surface->current.committed = E_SURFACE_STATE_CLEAN;
}
static void
+#include "e_compositor_intern.h"
#include "e_presentation_time_intern.h"
#include "e_comp_wl_intern.h"
#include "e_client_intern.h"
struct wl_resource *surface_resource,
uint32_t callback)
{
- E_Client *ec;
- E_Comp_Wl_Client_Data *cdata;
+ E_Surface *surface = e_surface_from_resource(surface_resource);
E_Presentation_Time_Feedback *feedback;
- ec = e_client_from_surface_resource(surface_resource);
- if (!ec) return;
- if (e_object_is_del(E_OBJECT(ec))) return;
- cdata = e_client_cdata_get(ec);
- if (!cdata) return;
-
feedback = E_NEW(E_Presentation_Time_Feedback, 1);
if (!feedback)
{
PRSTT_TRACE("feedback:%p Create", NULL, feedback);
- e_presentation_time_container_feedback_set(&cdata->pending.presentation_container,
- feedback);
+ e_surface_presentation_time_feedback_add(surface, feedback);
}
static void