static void
clutter_stage_egl_dispose (GObject *gobject)
{
  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (gobject);

  G_OBJECT_CLASS (clutter_stage_egl_parent_class)->dispose (gobject);
}
Example #2
0
static ClutterActor *
clutter_backend_egl_create_stage (ClutterBackend  *backend,
                                  ClutterStage    *wrapper,
                                  GError         **error)
{
    ClutterBackendEGL *backend_egl = CLUTTER_BACKEND_EGL (backend);
    ClutterStageEGL   *stage_egl;
    ClutterActor      *stage;

    if (backend_egl->stage)
    {
        g_warning ("The EGL native backend does not support multiple stages");
        return backend_egl->stage;
    }

    stage = g_object_new (CLUTTER_TYPE_STAGE_FRUITY, NULL);

    stage_egl = CLUTTER_STAGE_EGL (stage);
    stage_egl->backend = backend_egl;
    stage_egl->wrapper = wrapper;

    backend_egl->stage = CLUTTER_ACTOR (stage_egl);

    return stage;
}
Example #3
0
static void
clutter_stage_egl_hide (ClutterActor *actor)
{
  CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_MAPPED);
  CLUTTER_ACTOR_UNSET_FLAGS (CLUTTER_STAGE_EGL (actor)->wrapper,
                             CLUTTER_ACTOR_MAPPED);
}
static void
clutter_stage_egl_get_preferred_height (ClutterActor *self,
                                        gfloat        for_width,
                                        gfloat       *min_height_p,
                                        gfloat       *natural_height_p)
{
  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (self);

  if (min_height_p)
    *min_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_height);

  if (natural_height_p)
    *natural_height_p = CLUTTER_UNITS_FROM_DEVICE (stage_egl->surface_height);
}
Example #5
0
static void
clutter_backend_egl_redraw (ClutterBackend *backend,
                            ClutterStage   *stage)
{
  ClutterStageWindow *impl;

  impl = _clutter_stage_get_window (stage);
  if (!impl)
    return;

  g_assert (CLUTTER_IS_STAGE_EGL (impl));

  clutter_stage_egl_redraw (CLUTTER_STAGE_EGL (impl), stage);
}
static void
clutter_stage_egl_unrealize (ClutterActor *actor)
{
  ClutterStageEGL *stage_egl = CLUTTER_STAGE_EGL (actor);

  CLUTTER_MARK();

  if (CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->unrealize != NULL)
    CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->unrealize (actor);

  if (stage_egl->egl_surface)
    {
      eglDestroySurface (clutter_egl_display (), stage_egl->egl_surface);
      stage_egl->egl_surface = EGL_NO_SURFACE;
    }
}
static void
clutter_backend_egl_redraw (ClutterBackend *backend,
                            ClutterStage   *stage)
{
    ClutterBackendEGL  *backend_egl = CLUTTER_BACKEND_EGL (backend);
    ClutterStageEGL    *stage_egl;
    ClutterStageWindow *impl;

    impl = _clutter_stage_get_window (stage);
    if (!impl)
        return;

    g_assert (CLUTTER_IS_STAGE_EGL (impl));
    stage_egl = CLUTTER_STAGE_EGL (impl);

    eglWaitNative (EGL_CORE_NATIVE_ENGINE);
    clutter_actor_paint (CLUTTER_ACTOR (stage));
    cogl_flush ();
    eglWaitGL();
    eglSwapBuffers (backend_egl->edpy,  stage_egl->egl_surface);
}
static void
clutter_stage_egl_realize (ClutterActor *actor)
{
  ClutterStageEGL     *stage_egl = CLUTTER_STAGE_EGL (actor);
  ClutterBackendEGL   *backend_egl;
  EGLConfig            configs[2];
  EGLint               config_count;
  EGLBoolean           status;
  gboolean             is_offscreen;

  CLUTTER_NOTE (BACKEND, "Realizing main stage");

  g_object_get (stage_egl->wrapper, "offscreen", &is_offscreen, NULL);

  backend_egl = CLUTTER_BACKEND_EGL (clutter_get_default_backend ());

  if (G_LIKELY (!is_offscreen))
    {
      EGLint cfg_attribs[] = { EGL_BUFFER_SIZE,    EGL_DONT_CARE,
			       EGL_RED_SIZE,       5,
			       EGL_GREEN_SIZE,     6,
			       EGL_BLUE_SIZE,      5,
			       EGL_DEPTH_SIZE,     16,
			       EGL_ALPHA_SIZE,     EGL_DONT_CARE,
			       EGL_STENCIL_SIZE,   2,
			       EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
			       EGL_NONE };

      status = eglGetConfigs (backend_egl->edpy,
			      configs, 
			      2, 
			      &config_count);

      if (status != EGL_TRUE)
	g_warning ("eglGetConfigs failed");

      status = eglChooseConfig (backend_egl->edpy,
				cfg_attribs,
				configs,
                                G_N_ELEMENTS (configs),
				&config_count);

      if (status != EGL_TRUE)
        {
	  g_critical ("eglChooseConfig failed");
          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }

      if (stage_egl->egl_surface != EGL_NO_SURFACE)
        {
	  eglDestroySurface (backend_egl->edpy, stage_egl->egl_surface);
          stage_egl->egl_surface = EGL_NO_SURFACE;
        }

       if (backend_egl->egl_context)
         {
            eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
            backend_egl->egl_context = NULL;
         }

      stage_egl->egl_surface =
	eglCreateWindowSurface (backend_egl->edpy,
                                configs[0],
                                NULL,
                                NULL);



      if (stage_egl->egl_surface == EGL_NO_SURFACE)
        {
	  g_critical ("Unable to create an EGL surface");
          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }

      eglQuerySurface (backend_egl->edpy,
		       stage_egl->egl_surface,
		       EGL_WIDTH,
		       &stage_egl->surface_width);

      eglQuerySurface (backend_egl->edpy,
		       stage_egl->egl_surface,
		       EGL_HEIGHT,
		       &stage_egl->surface_height);

      CLUTTER_NOTE (BACKEND, "EGL surface is %ix%i", 
		    stage_egl->surface_width,
                    stage_egl->surface_height);


      if (G_UNLIKELY (backend_egl->egl_context == NULL))
        {
          CLUTTER_NOTE (GL, "Creating EGL Context");

          backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
                                                       configs[0],
                                                       EGL_NO_CONTEXT,
                                                       NULL);

          if (backend_egl->egl_context == EGL_NO_CONTEXT)
            {
              g_critical ("Unable to create a suitable EGL context");

              CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
              return;
            }
        }

      /* this will make sure to set the current context */
      CLUTTER_NOTE (BACKEND, "Setting context");

      /* this should be done in ClutterBackend::ensure_context */
      status = eglMakeCurrent (backend_egl->edpy,
                               stage_egl->egl_surface,
                               stage_egl->egl_surface,
                               backend_egl->egl_context);

      if (status != EGL_TRUE)
        {
          g_critical ("eglMakeCurrent failed");
          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }
    }
  else
    {
      g_warning("EGL Backend does not yet support offscreen rendering\n");
      CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
    }
}
static ClutterActor *
clutter_stage_egl_get_wrapper (ClutterStageWindow *stage_window)
{
  return CLUTTER_ACTOR (CLUTTER_STAGE_EGL (stage_window)->wrapper);
}
Example #10
0
static void
clutter_backend_egl_ensure_context (ClutterBackend *backend,
                                    ClutterStage   *stage)
{
  ClutterBackendEGL  *backend_egl = CLUTTER_BACKEND_EGL (backend);
  ClutterStageWindow *impl;

  if (stage == NULL ||
      (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_IN_DESTRUCTION) ||
      ((impl = _clutter_stage_get_window (stage)) == NULL))
    {
      CLUTTER_NOTE (BACKEND, "Clearing EGL context");
      eglMakeCurrent (backend_egl->edpy,
                      EGL_NO_SURFACE,
                      EGL_NO_SURFACE,
                      EGL_NO_CONTEXT);
    }
  else
    {
      ClutterStageEGL    *stage_egl;
      ClutterStageX11    *stage_x11;

      g_assert (impl != NULL);

      CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
                    g_type_name (G_OBJECT_TYPE (impl)),
                    impl);

      stage_egl = CLUTTER_STAGE_EGL (impl);
      stage_x11 = CLUTTER_STAGE_X11 (impl);

      if (backend_egl->egl_context == EGL_NO_CONTEXT)
        return;

      clutter_x11_trap_x_errors ();

      /* we might get here inside the final dispose cycle, so we
       * need to handle this gracefully
       */
      if (stage_x11->xwin == None ||
          stage_egl->egl_surface == EGL_NO_SURFACE)
        {
          CLUTTER_NOTE (MULTISTAGE,
                        "Received a stale stage, clearing all context");

          if (backend_egl->dummy_surface == EGL_NO_SURFACE)
            eglMakeCurrent (backend_egl->edpy,
                            EGL_NO_SURFACE,
                            EGL_NO_SURFACE,
                            EGL_NO_CONTEXT);
          else
            eglMakeCurrent (backend_egl->edpy,
                            backend_egl->dummy_surface,
                            backend_egl->dummy_surface,
                            backend_egl->egl_context);
        }
      else
        {
          CLUTTER_NOTE (MULTISTAGE, "Setting real surface current");
          eglMakeCurrent (backend_egl->edpy,
                          stage_egl->egl_surface,
                          stage_egl->egl_surface,
                          backend_egl->egl_context);
        }

      if (clutter_x11_untrap_x_errors ())
        g_critical ("Unable to make the stage window 0x%x the current "
                    "EGLX drawable",
                    (int) stage_x11->xwin);
    }
}
Example #11
0
static void
clutter_stage_egl_realize (ClutterActor *actor)
{
  ClutterStageEGL     *stage_egl = CLUTTER_STAGE_EGL (actor);
  ClutterBackendEGL   *backend_egl;
  EGLConfig            configs[2];
  EGLint               config_count;
  EGLBoolean           status;
  gboolean             is_offscreen;

  CLUTTER_NOTE (BACKEND, "Realizing main stage");

  g_object_get (stage_egl->wrapper, "offscreen", &is_offscreen, NULL);

  backend_egl = CLUTTER_BACKEND_EGL (clutter_get_default_backend ());

  if (G_LIKELY (!is_offscreen))
    {
      EGLint cfg_attribs[] = { EGL_BUFFER_SIZE,     EGL_DONT_CARE,
			       EGL_RED_SIZE,        5,
			       EGL_GREEN_SIZE,      6,
			       EGL_BLUE_SIZE,       5,
			       EGL_DEPTH_SIZE,      16,
			       EGL_ALPHA_SIZE,      EGL_DONT_CARE,
			       EGL_STENCIL_SIZE,    2, 
#ifdef HAVE_COGL_GLES2
			       EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#else /* HAVE_COGL_GLES2 */
			       EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
#endif /* HAVE_COGL_GLES2 */
			       EGL_NONE };

      status = eglGetConfigs (backend_egl->edpy,
			      configs, 
			      2, 
			      &config_count);

      if (status != EGL_TRUE)
        {
	  g_critical ("eglGetConfigs failed");
          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }

      status = eglChooseConfig (backend_egl->edpy,
				cfg_attribs,
				configs,
                                G_N_ELEMENTS (configs),
				&config_count);

      if (status != EGL_TRUE)
        {
          g_critical ("eglChooseConfig failed");
          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }

      CLUTTER_NOTE (BACKEND, "Got %i configs", config_count); 

      if (stage_egl->egl_surface != EGL_NO_SURFACE)
        {
	  eglDestroySurface (backend_egl->edpy, stage_egl->egl_surface);
          stage_egl->egl_surface = EGL_NO_SURFACE;
        }

       if (backend_egl->egl_context)
         {
            eglDestroyContext (backend_egl->edpy, backend_egl->egl_context);
            backend_egl->egl_context = NULL;
         }

      stage_egl->egl_surface =
	eglCreateWindowSurface (backend_egl->edpy,
                                configs[0],
                                NULL,
                                NULL);

      if (stage_egl->egl_surface == EGL_NO_SURFACE)
        {
	  g_critical ("Unable to create an EGL surface");

          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }

      eglQuerySurface (backend_egl->edpy,
		       stage_egl->egl_surface,
		       EGL_WIDTH,
		       &stage_egl->surface_width);

      eglQuerySurface (backend_egl->edpy,
		       stage_egl->egl_surface,
		       EGL_HEIGHT,
		       &stage_egl->surface_height);

      CLUTTER_NOTE (BACKEND, "EGL surface is %ix%i", 
		    stage_egl->surface_width,
                    stage_egl->surface_height);

      
      if (G_UNLIKELY (backend_egl->egl_context == NULL))
        {
#ifdef HAVE_COGL_GLES2
	  static const EGLint attribs[3]
	    = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };

          backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
						       configs[0],
                                                       EGL_NO_CONTEXT,
                                                       attribs);
#else
          /* Seems some GLES implementations 1.x do not like attribs... */
          backend_egl->egl_context = eglCreateContext (backend_egl->edpy,
						       configs[0],
                                                       EGL_NO_CONTEXT,
                                                       NULL);
#endif

          if (backend_egl->egl_context == EGL_NO_CONTEXT)
            {
              g_critical ("Unable to create a suitable EGL context");

              CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
              return;
            }

          CLUTTER_NOTE (GL, "Created EGL Context");
        }

      CLUTTER_NOTE (BACKEND, "Setting context");

      /* eglnative can have only one stage */
      status = eglMakeCurrent (backend_egl->edpy,
                               stage_egl->egl_surface,
                               stage_egl->egl_surface,
                               backend_egl->egl_context);

      if (status != EGL_TRUE)
        {
          g_critical ("eglMakeCurrent failed");
          
          CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
          return;
        }

      /* since we only have one size and it cannot change, we
       * just need to update the GL viewport now that we have
       * been realized
       */
      CLUTTER_SET_PRIVATE_FLAGS (actor, CLUTTER_ACTOR_SYNC_MATRICES);
    }
  else
    {
      g_warning ("EGL Backend does not yet support offscreen rendering\n");
      CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
      return;
    }
}