#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "clutter-backend-egl.h" #include "clutter-stage-egl.h" #include "../clutter-private.h" #include "../clutter-main.h" #include "../clutter-debug.h" static ClutterBackendEGL *backend_singleton = NULL; G_DEFINE_TYPE (ClutterBackendEGL, clutter_backend_egl, CLUTTER_TYPE_BACKEND); static gboolean clutter_backend_egl_pre_parse (ClutterBackend *backend, GError **error) { return TRUE; } static gboolean clutter_backend_egl_post_parse (ClutterBackend *backend, GError **error) { ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL(backend); EGLBoolean status; backend_egl->edpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); status = eglInitialize(backend_egl->edpy, &backend_egl->egl_version_major, &backend_egl->egl_version_minor); if (status != EGL_TRUE) { g_set_error (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_BACKEND, "Unable to Initialize EGL"); return FALSE; } CLUTTER_NOTE (BACKEND, "EGL Reports version %i.%i", backend_egl->egl_version_major, backend_egl->egl_version_minor); return TRUE; } static gboolean clutter_backend_egl_init_stage (ClutterBackend *backend, GError **error) { ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend); if (!backend_egl->stage) { ClutterActor *stage; stage = g_object_new (CLUTTER_TYPE_STAGE_EGL, NULL); g_object_set_data (G_OBJECT (stage), "clutter-backend", backend); backend_egl->stage = g_object_ref_sink (stage); } clutter_actor_realize (backend_egl->stage); if (!CLUTTER_ACTOR_IS_REALIZED (backend_egl->stage)) { g_set_error (error, CLUTTER_INIT_ERROR, CLUTTER_INIT_ERROR_INTERNAL, "Unable to realize the main stage"); return FALSE; } return TRUE; } static void clutter_backend_egl_init_events (ClutterBackend *backend) { _clutter_events_init (backend); } static const GOptionEntry entries[] = { { NULL } }; static void clutter_backend_egl_redraw (ClutterBackend *backend) { ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend); ClutterStageEGL *stage_egl; stage_egl = CLUTTER_STAGE_EGL(backend_egl->stage); clutter_actor_paint (CLUTTER_ACTOR(stage_egl)); /* Why this paint is done in backend as likely GL windowing system * specific calls, like swapping buffers. */ /* clutter_feature_wait_for_vblank (); */ eglSwapBuffers (backend_egl->edpy, stage_egl->egl_surface); } static ClutterActor * clutter_backend_egl_get_stage (ClutterBackend *backend) { ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend); return backend_egl->stage; } static void clutter_backend_egl_finalize (GObject *gobject) { if (backend_singleton) backend_singleton = NULL; G_OBJECT_CLASS (clutter_backend_egl_parent_class)->finalize (gobject); } static void clutter_backend_egl_dispose (GObject *gobject) { ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (gobject); _clutter_events_uninit (CLUTTER_BACKEND (backend_egl)); if (backend_egl->stage) { clutter_actor_destroy (backend_egl->stage); backend_egl->stage = NULL; } if (backend_egl->edpy) { eglTerminate (backend_egl->edpy); backend_egl->edpy = NULL; } G_OBJECT_CLASS (clutter_backend_egl_parent_class)->dispose (gobject); } static GObject * clutter_backend_egl_constructor (GType gtype, guint n_params, GObjectConstructParam *params) { GObjectClass *parent_class; GObject *retval; if (!backend_singleton) { parent_class = G_OBJECT_CLASS (clutter_backend_egl_parent_class); retval = parent_class->constructor (gtype, n_params, params); backend_singleton = CLUTTER_BACKEND_EGL (retval); return retval; } g_warning ("Attempting to create a new backend object. This should " "never happen, so we return the singleton instance."); return g_object_ref (backend_singleton); } static ClutterFeatureFlags clutter_backend_egl_get_features (ClutterBackend *backend) { return CLUTTER_FEATURE_STAGE_STATIC; } static void clutter_backend_egl_class_init (ClutterBackendEGLClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterBackendClass *backend_class = CLUTTER_BACKEND_CLASS (klass); gobject_class->constructor = clutter_backend_egl_constructor; gobject_class->dispose = clutter_backend_egl_dispose; gobject_class->finalize = clutter_backend_egl_finalize; backend_class->pre_parse = clutter_backend_egl_pre_parse; backend_class->post_parse = clutter_backend_egl_post_parse; backend_class->init_stage = clutter_backend_egl_init_stage; backend_class->init_events = clutter_backend_egl_init_events; backend_class->get_stage = clutter_backend_egl_get_stage; backend_class->redraw = clutter_backend_egl_redraw; backend_class->get_features = clutter_backend_egl_get_features; } static void clutter_backend_egl_init (ClutterBackendEGL *backend_egl) { ClutterBackend *backend = CLUTTER_BACKEND (backend_egl); clutter_backend_set_resolution (backend, 96.0); clutter_backend_set_double_click_time (backend, 250); clutter_backend_set_double_click_distance (backend, 5); } GType _clutter_backend_impl_get_type (void) { return clutter_backend_egl_get_type (); } EGLDisplay clutter_egl_display (void) { return backend_singleton->edpy; }