mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
ClutterStageCogl: Let the sub-classes handle the onscreen
In preperation for having allowing drawing onto multiple onscreen framebuffers, move the onscreen framebuffer handling to the corresponding winsys dependent backends. Currently the onscreen framebuffer is still accessed, but, as can seen by the usage of "legacy" in the accessor name, it should be considered the legacy method. Eventually only the X11 Compositing Manager backend will make use of the legacy single onscreen framebuffer API. https://bugzilla.gnome.org/show_bug.cgi?id=768976
This commit is contained in:
parent
df0805fb0a
commit
767e12125b
@ -62,6 +62,7 @@
|
||||
#include "clutter-feature.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-master-clock.h"
|
||||
#include "clutter-mutter.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-settings-private.h"
|
||||
#include "clutter-stage-manager.h"
|
||||
|
@ -33,6 +33,9 @@
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean _clutter_get_sync_to_vblank (void);
|
||||
|
||||
#undef __CLUTTER_H_INSIDE__
|
||||
|
||||
#endif /* __CLUTTER_MUTTER_H__ */
|
||||
|
@ -210,7 +210,6 @@ void _clutter_id_to_color (guint id,
|
||||
ClutterColor *col);
|
||||
|
||||
void _clutter_set_sync_to_vblank (gboolean sync_to_vblank);
|
||||
gboolean _clutter_get_sync_to_vblank (void);
|
||||
|
||||
/* use this function as the accumulator if you have a signal with
|
||||
* a G_TYPE_BOOLEAN return value; this will stop the emission as
|
||||
|
@ -348,3 +348,41 @@ _clutter_stage_window_get_scale_factor (ClutterStageWindow *window)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
CoglFramebuffer *
|
||||
_clutter_stage_window_get_legacy_onscreen (ClutterStageWindow *window)
|
||||
{
|
||||
ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
|
||||
return iface->get_legacy_onscreen (window);
|
||||
}
|
||||
|
||||
CoglFrameClosure *
|
||||
_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
|
||||
CoglFrameCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
|
||||
return iface->set_frame_callback (window, callback, user_data);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_window_remove_frame_callback (ClutterStageWindow *window,
|
||||
CoglFrameClosure *closure)
|
||||
{
|
||||
ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
|
||||
iface->remove_frame_callback (window, closure);
|
||||
}
|
||||
|
||||
int64_t
|
||||
_clutter_stage_window_get_frame_counter (ClutterStageWindow *window)
|
||||
{
|
||||
ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
|
||||
if (iface->get_frame_counter)
|
||||
return iface->get_frame_counter (window);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -86,6 +86,13 @@ struct _ClutterStageWindowIface
|
||||
void (* set_scale_factor) (ClutterStageWindow *stage_window,
|
||||
int factor);
|
||||
int (* get_scale_factor) (ClutterStageWindow *stage_window);
|
||||
CoglFramebuffer *(* get_legacy_onscreen) (ClutterStageWindow *stage_window);
|
||||
CoglFrameClosure *(* set_frame_callback) (ClutterStageWindow *stage_window,
|
||||
CoglFrameCallback callback,
|
||||
gpointer user_data);
|
||||
void (* remove_frame_callback) (ClutterStageWindow *stage_window,
|
||||
CoglFrameClosure *closure);
|
||||
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
@ -142,6 +149,17 @@ void _clutter_stage_window_set_scale_factor (ClutterStageWin
|
||||
int factor);
|
||||
int _clutter_stage_window_get_scale_factor (ClutterStageWindow *window);
|
||||
|
||||
CoglFramebuffer *_clutter_stage_window_get_legacy_onscreen (ClutterStageWindow *stage_window);
|
||||
|
||||
CoglFrameClosure *_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
|
||||
CoglFrameCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void _clutter_stage_window_remove_frame_callback (ClutterStageWindow *stage_winow,
|
||||
CoglFrameClosure *closure);
|
||||
|
||||
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STAGE_WINDOW_H__ */
|
||||
|
@ -69,6 +69,7 @@
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-master-clock.h"
|
||||
#include "clutter-mutter.h"
|
||||
#include "clutter-paint-volume-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-manager-private.h"
|
||||
|
@ -68,14 +68,11 @@ clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_cogl);
|
||||
|
||||
if (stage_cogl->onscreen != NULL)
|
||||
if (stage_cogl->frame_closure != NULL)
|
||||
{
|
||||
cogl_onscreen_remove_frame_callback (stage_cogl->onscreen,
|
||||
stage_cogl->frame_closure);
|
||||
_clutter_stage_window_remove_frame_callback (stage_window,
|
||||
stage_cogl->frame_closure);
|
||||
stage_cogl->frame_closure = NULL;
|
||||
|
||||
cogl_object_unref (stage_cogl->onscreen);
|
||||
stage_cogl->onscreen = NULL;
|
||||
}
|
||||
|
||||
stage_cogl->pending_swaps = 0;
|
||||
@ -126,10 +123,6 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
ClutterBackend *backend;
|
||||
CoglFramebuffer *framebuffer;
|
||||
GError *error = NULL;
|
||||
gfloat width = 800;
|
||||
gfloat height = 600;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Realizing stage '%s' [%p]",
|
||||
G_OBJECT_TYPE_NAME (stage_cogl),
|
||||
@ -143,34 +136,10 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (stage_cogl->onscreen == NULL)
|
||||
{
|
||||
stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
|
||||
width, height);
|
||||
}
|
||||
|
||||
cogl_onscreen_set_swap_throttled (stage_cogl->onscreen,
|
||||
_clutter_get_sync_to_vblank ());
|
||||
|
||||
framebuffer = COGL_FRAMEBUFFER (stage_cogl->onscreen);
|
||||
if (!cogl_framebuffer_allocate (framebuffer, &error))
|
||||
{
|
||||
g_warning ("Failed to allocate stage: %s", error->message);
|
||||
g_error_free (error);
|
||||
cogl_object_unref (stage_cogl->onscreen);
|
||||
stage_cogl->onscreen = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: for fullscreen Cogl platforms then the size we gave
|
||||
* will be ignored, so we need to make sure the stage size is
|
||||
* updated to this size. */
|
||||
|
||||
stage_cogl->frame_closure =
|
||||
cogl_onscreen_add_frame_callback (stage_cogl->onscreen,
|
||||
frame_cb,
|
||||
stage_cogl,
|
||||
NULL);
|
||||
_clutter_stage_window_set_frame_callback (stage_window,
|
||||
frame_cb, stage_window);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -262,36 +231,6 @@ clutter_stage_cogl_hide (ClutterStageWindow *stage_window)
|
||||
clutter_actor_unmap (CLUTTER_ACTOR (stage_cogl->wrapper));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_get_geometry (ClutterStageWindow *stage_window,
|
||||
cairo_rectangle_int_t *geometry)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
int window_scale;
|
||||
|
||||
window_scale = _clutter_stage_window_get_scale_factor (stage_window);
|
||||
|
||||
if (geometry != NULL)
|
||||
{
|
||||
if (stage_cogl->onscreen)
|
||||
{
|
||||
CoglFramebuffer *framebuffer =
|
||||
COGL_FRAMEBUFFER (stage_cogl->onscreen);
|
||||
|
||||
geometry->x = geometry->y = 0;
|
||||
|
||||
geometry->width = cogl_framebuffer_get_width (framebuffer) / window_scale;
|
||||
geometry->height = cogl_framebuffer_get_height (framebuffer) / window_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry->x = geometry->y = 0;
|
||||
geometry->width = 800;
|
||||
geometry->height = 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_resize (ClutterStageWindow *stage_window,
|
||||
gint width,
|
||||
@ -414,6 +353,7 @@ static void
|
||||
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
CoglOnscreen *onscreen;
|
||||
cairo_rectangle_int_t geom;
|
||||
gboolean have_clip;
|
||||
gboolean may_use_clipped_redraw;
|
||||
@ -428,7 +368,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
|
||||
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
|
||||
|
||||
if (!stage_cogl->onscreen)
|
||||
onscreen = _clutter_stage_window_get_legacy_onscreen (stage_window);
|
||||
if (!onscreen)
|
||||
return;
|
||||
|
||||
can_blit_sub_buffer =
|
||||
@ -476,7 +417,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
int age = cogl_onscreen_get_buffer_age (stage_cogl->onscreen), i;
|
||||
int age = cogl_onscreen_get_buffer_age (onscreen), i;
|
||||
|
||||
*current_damage = *clip_region;
|
||||
|
||||
@ -512,7 +453,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
CoglFramebuffer *fb = COGL_FRAMEBUFFER (stage_cogl->onscreen);
|
||||
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING,
|
||||
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
||||
@ -551,7 +492,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
if (may_use_clipped_redraw &&
|
||||
G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_REDRAWS)))
|
||||
{
|
||||
CoglFramebuffer *fb = COGL_FRAMEBUFFER (stage_cogl->onscreen);
|
||||
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *ctx = cogl_framebuffer_get_context (fb);
|
||||
static CoglPipeline *outline = NULL;
|
||||
cairo_rectangle_int_t *clip = &stage_cogl->bounding_redraw_clip;
|
||||
@ -584,7 +525,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
cogl_matrix_init_identity (&modelview);
|
||||
_clutter_actor_apply_modelview_transform (actor, &modelview);
|
||||
cogl_framebuffer_set_modelview_matrix (fb, &modelview);
|
||||
cogl_framebuffer_draw_primitive (COGL_FRAMEBUFFER (stage_cogl->onscreen),
|
||||
cogl_framebuffer_draw_primitive (COGL_FRAMEBUFFER (onscreen),
|
||||
outline,
|
||||
prim);
|
||||
cogl_framebuffer_pop_matrix (fb);
|
||||
@ -619,16 +560,16 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
"cogl_onscreen_swap_region (onscreen: %p, "
|
||||
"x: %d, y: %d, "
|
||||
"width: %d, height: %d)",
|
||||
stage_cogl->onscreen,
|
||||
onscreen,
|
||||
damage[0], damage[1], damage[2], damage[3]);
|
||||
|
||||
cogl_onscreen_swap_region (stage_cogl->onscreen,
|
||||
cogl_onscreen_swap_region (onscreen,
|
||||
damage, ndamage);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "cogl_onscreen_swap_buffers (onscreen: %p)",
|
||||
stage_cogl->onscreen);
|
||||
onscreen);
|
||||
|
||||
/* If we have swap buffer events then cogl_onscreen_swap_buffers
|
||||
* will return immediately and we need to track that there is a
|
||||
@ -636,7 +577,7 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS))
|
||||
stage_cogl->pending_swaps++;
|
||||
|
||||
cogl_onscreen_swap_buffers_with_damage (stage_cogl->onscreen,
|
||||
cogl_onscreen_swap_buffers_with_damage (onscreen,
|
||||
damage, ndamage);
|
||||
}
|
||||
|
||||
@ -649,9 +590,10 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
static CoglFramebuffer *
|
||||
clutter_stage_cogl_get_active_framebuffer (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
CoglOnscreen *onscreen =
|
||||
_clutter_stage_window_get_legacy_onscreen (stage_window);
|
||||
|
||||
return COGL_FRAMEBUFFER (stage_cogl->onscreen);
|
||||
return COGL_FRAMEBUFFER (onscreen);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -683,7 +625,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
iface->realize = clutter_stage_cogl_realize;
|
||||
iface->unrealize = clutter_stage_cogl_unrealize;
|
||||
iface->get_wrapper = clutter_stage_cogl_get_wrapper;
|
||||
iface->get_geometry = clutter_stage_cogl_get_geometry;
|
||||
iface->resize = clutter_stage_cogl_resize;
|
||||
iface->show = clutter_stage_cogl_show;
|
||||
iface->hide = clutter_stage_cogl_hide;
|
||||
|
@ -35,8 +35,6 @@ struct _ClutterStageCogl
|
||||
/* back pointer to the backend */
|
||||
ClutterBackend *backend;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
|
||||
float refresh_rate;
|
||||
int pending_swaps;
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-feature.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-mutter.h"
|
||||
#include "clutter-paint-volume-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
@ -439,10 +440,12 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
||||
* 1x1 one if we're unrealizing the current one, so Cogl doesn't
|
||||
* keep any reference to the foreign window.
|
||||
*/
|
||||
if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_cogl->onscreen))
|
||||
if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_x11->onscreen))
|
||||
_clutter_backend_reset_cogl_framebuffer (stage_cogl->backend);
|
||||
|
||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||
|
||||
g_clear_pointer (&stage_x11->onscreen, cogl_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -608,6 +611,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||
ClutterDeviceManager *device_manager;
|
||||
gfloat width, height;
|
||||
GError *error = NULL;
|
||||
|
||||
clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper), &width, &height);
|
||||
|
||||
@ -620,7 +624,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
width, height,
|
||||
stage_x11->scale_factor);
|
||||
|
||||
stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
|
||||
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
|
||||
|
||||
/* We just created a window of the size of the actor. No need to fix
|
||||
the size of the stage, just update it. */
|
||||
@ -629,21 +633,26 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
cogl_x11_onscreen_set_foreign_window_xid (stage_cogl->onscreen,
|
||||
cogl_x11_onscreen_set_foreign_window_xid (stage_x11->onscreen,
|
||||
stage_x11->xwin,
|
||||
_clutter_stage_x11_update_foreign_event_mask,
|
||||
stage_x11);
|
||||
|
||||
}
|
||||
|
||||
/* Chain to the parent class now. ClutterStageCogl will call cogl_framebuffer_allocate,
|
||||
which will create the X Window we need */
|
||||
if (!cogl_framebuffer_allocate (stage_x11->onscreen, &error))
|
||||
{
|
||||
g_warning ("Failed to allocate stage: %s", error->message);
|
||||
g_error_free (error);
|
||||
cogl_object_unref (stage_x11->onscreen);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (!(clutter_stage_window_parent_iface->realize (stage_window)))
|
||||
return FALSE;
|
||||
|
||||
if (stage_x11->xwin == None)
|
||||
stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_cogl->onscreen);
|
||||
stage_x11->xwin = cogl_x11_onscreen_get_window_xid (stage_x11->onscreen);
|
||||
|
||||
if (clutter_stages_by_xid == NULL)
|
||||
clutter_stages_by_xid = g_hash_table_new (NULL, NULL);
|
||||
@ -883,6 +892,47 @@ clutter_stage_x11_get_scale_factor (ClutterStageWindow *stage_window)
|
||||
return stage_x11->scale_factor;
|
||||
}
|
||||
|
||||
static CoglFramebuffer *
|
||||
clutter_stage_x11_get_legacy_onscreen (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
return stage_x11->onscreen;
|
||||
}
|
||||
|
||||
static CoglFrameClosure *
|
||||
clutter_stage_x11_set_frame_callback (ClutterStageWindow *stage_window,
|
||||
CoglFrameCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
|
||||
_clutter_get_sync_to_vblank ());
|
||||
|
||||
return cogl_onscreen_add_frame_callback (stage_x11->onscreen,
|
||||
callback,
|
||||
user_data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_remove_frame_callback (ClutterStageWindow *stage_window,
|
||||
CoglFrameClosure *closure)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
cogl_onscreen_remove_frame_callback (stage_x11->onscreen, closure);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
clutter_stage_x11_get_frame_counter (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
return cogl_onscreen_get_frame_counter (stage_x11->onscreen);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_finalize (GObject *gobject)
|
||||
{
|
||||
@ -957,6 +1007,10 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws;
|
||||
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
|
||||
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
|
||||
iface->get_legacy_onscreen = clutter_stage_x11_get_legacy_onscreen;
|
||||
iface->set_frame_callback = clutter_stage_x11_set_frame_callback;
|
||||
iface->remove_frame_callback = clutter_stage_x11_remove_frame_callback;
|
||||
iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -53,6 +53,7 @@ struct _ClutterStageX11
|
||||
{
|
||||
ClutterStageCogl parent_instance;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
Window xwin;
|
||||
gint xwin_width;
|
||||
gint xwin_height; /* FIXME target_width / height */
|
||||
|
@ -26,11 +26,20 @@
|
||||
|
||||
#include "backends/native/meta-stage-native.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "meta/meta-backend.h"
|
||||
#include "meta/meta-monitor-manager.h"
|
||||
#include "meta/util.h"
|
||||
|
||||
struct _MetaStageNative
|
||||
{
|
||||
ClutterStageCogl parent;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
};
|
||||
|
||||
static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
|
||||
|
||||
static void
|
||||
clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
|
||||
|
||||
@ -38,12 +47,108 @@ G_DEFINE_TYPE_WITH_CODE (MetaStageNative, meta_stage_native,
|
||||
CLUTTER_TYPE_STAGE_COGL,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||
clutter_stage_window_iface_init))
|
||||
static gboolean
|
||||
meta_stage_native_realize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
ClutterBackend *clutter_backend = CLUTTER_BACKEND (stage_cogl->backend);
|
||||
GError *error = NULL;
|
||||
|
||||
stage_native->onscreen = cogl_onscreen_new (clutter_backend->cogl_context,
|
||||
1, 1);
|
||||
|
||||
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (stage_native->onscreen),
|
||||
&error))
|
||||
meta_fatal ("Failed to allocate onscreen framebuffer: %s\n",
|
||||
error->message);
|
||||
|
||||
if (!(clutter_stage_window_parent_iface->realize (stage_window)))
|
||||
meta_fatal ("Failed to realize native stage window");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_native_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
|
||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||
|
||||
g_clear_pointer (&stage_native->onscreen, cogl_object_unref);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_stage_native_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_native_get_geometry (ClutterStageWindow *stage_window,
|
||||
cairo_rectangle_int_t *geometry)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (stage_native->onscreen);
|
||||
|
||||
if (framebuffer)
|
||||
{
|
||||
*geometry = (cairo_rectangle_int_t) {
|
||||
.width = cogl_framebuffer_get_width (framebuffer),
|
||||
.height = cogl_framebuffer_get_height (framebuffer)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
*geometry = (cairo_rectangle_int_t) {
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static CoglFramebuffer *
|
||||
meta_stage_native_get_legacy_onscreen (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
|
||||
return COGL_FRAMEBUFFER (stage_native->onscreen);
|
||||
}
|
||||
|
||||
static CoglClosure *
|
||||
meta_stage_native_set_frame_callback (ClutterStageWindow *stage_window,
|
||||
CoglFrameCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
|
||||
cogl_onscreen_set_swap_throttled (stage_native->onscreen,
|
||||
_clutter_get_sync_to_vblank ());
|
||||
|
||||
return cogl_onscreen_add_frame_callback (stage_native->onscreen,
|
||||
callback,
|
||||
user_data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_native_remove_frame_callback (ClutterStageWindow *stage_window,
|
||||
CoglFrameClosure *closure)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
|
||||
cogl_onscreen_remove_frame_callback (stage_native->onscreen, closure);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
meta_stage_native_get_frame_counter (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
|
||||
return cogl_onscreen_get_frame_counter (stage_native->onscreen);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_native_init (MetaStageNative *stage_native)
|
||||
{
|
||||
@ -57,5 +162,14 @@ meta_stage_native_class_init (MetaStageNativeClass *klass)
|
||||
static void
|
||||
clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
{
|
||||
clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->realize = meta_stage_native_realize;
|
||||
iface->unrealize = meta_stage_native_unrealize;
|
||||
iface->can_clip_redraws = meta_stage_native_can_clip_redraws;
|
||||
iface->get_geometry = meta_stage_native_get_geometry;
|
||||
iface->get_legacy_onscreen = meta_stage_native_get_legacy_onscreen;
|
||||
iface->set_frame_callback = meta_stage_native_set_frame_callback;
|
||||
iface->remove_frame_callback = meta_stage_native_remove_frame_callback;
|
||||
iface->get_frame_counter = meta_stage_native_get_frame_counter;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user