[cogl/wip/runtime-egl-platform: 11/12] egl-null: Support Mesa's null renderer



commit 77f39a536bd7925b3c07430f7be0a32e55457902
Author: Neil Roberts <neil linux intel com>
Date:   Tue Dec 13 00:00:22 2011 +0000

    egl-null: Support Mesa's null renderer
    
    Mesa supports a null renderer via the EGL_KHR_surfaceless extension to
    avoid binding a surface to the context. That way it can be used for
    completely offscreen renderering. The previous NULL winsys in Cogl was
    only intended for PowerVR's null renderer system which means a surface
    can be created by passing a NULL NativeWindowType. We can conflate
    these two renderers by checking for the surfaceless extension and
    avoiding trying to create the null surface until the first onscreen is
    created. That way if only offscreens are used it will also work under
    Mesa.

 cogl/winsys/cogl-winsys-egl-null.c |  100 +++++++++++++++++++++++++++---------
 1 files changed, 76 insertions(+), 24 deletions(-)
---
diff --git a/cogl/winsys/cogl-winsys-egl-null.c b/cogl/winsys/cogl-winsys-egl-null.c
index f0b9200..cdbe82e 100644
--- a/cogl/winsys/cogl-winsys-egl-null.c
+++ b/cogl/winsys/cogl-winsys-egl-null.c
@@ -39,8 +39,6 @@ static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
 
 typedef struct _CoglDisplayNull
 {
-  int egl_surface_width;
-  int egl_surface_height;
   gboolean have_onscreen;
 } CoglDisplayNull;
 
@@ -84,18 +82,41 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
   CoglRenderer *renderer = display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglDisplayEGL *egl_display = display->winsys;
-  CoglDisplayNull *null_display = egl_display->platform;
+  CoglEGLWinsysFeature surfaceless_feature = 0;
   const char *error_message;
 
-  egl_display->egl_surface =
-    eglCreateWindowSurface (egl_renderer->edpy,
-                            egl_display->egl_config,
-                            (NativeWindowType) NULL,
-                            NULL);
-  if (egl_display->egl_surface == EGL_NO_SURFACE)
+  switch (display->renderer->driver)
     {
-      error_message = "Unable to create EGL window surface";
-      goto fail;
+    case COGL_DRIVER_GL:
+      surfaceless_feature = COGL_EGL_WINSYS_FEATURE_SURFACELESS_OPENGL;
+      break;
+    case COGL_DRIVER_GLES1:
+      surfaceless_feature = COGL_EGL_WINSYS_FEATURE_SURFACELESS_GLES1;
+      break;
+    case COGL_DRIVER_GLES2:
+      surfaceless_feature = COGL_EGL_WINSYS_FEATURE_SURFACELESS_GLES2;
+      break;
+    }
+
+  /* If the driver supports the surfaceless extension we can delay
+     creating the window surface until the first onscreen is
+     created. That way the null window surface can be used on Mesa as
+     a totally offscreen context */
+
+  if ((egl_renderer->private_features & surfaceless_feature))
+    egl_display->egl_surface = EGL_NO_SURFACE;
+  else
+    {
+      egl_display->egl_surface =
+        eglCreateWindowSurface (egl_renderer->edpy,
+                                egl_display->egl_config,
+                                (NativeWindowType) NULL,
+                                NULL);
+      if (egl_display->egl_surface == EGL_NO_SURFACE)
+        {
+          error_message = "Unable to create EGL window surface";
+          goto fail;
+        }
     }
 
   if (!eglMakeCurrent (egl_renderer->edpy,
@@ -107,16 +128,6 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
       goto fail;
     }
 
-  eglQuerySurface (egl_renderer->edpy,
-                   egl_display->egl_surface,
-                   EGL_WIDTH,
-                   &null_display->egl_surface_width);
-
-  eglQuerySurface (egl_renderer->edpy,
-                   egl_display->egl_surface,
-                   EGL_HEIGHT,
-                   &null_display->egl_surface_height);
-
   return TRUE;
 
  fail:
@@ -172,6 +183,10 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
   CoglDisplayEGL *egl_display = display->winsys;
   CoglDisplayNull *null_display = egl_display->platform;
   CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+  CoglRenderer *renderer = display->renderer;
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+  int egl_surface_width;
+  int egl_surface_height;
 
   if (null_display->have_onscreen)
     {
@@ -181,11 +196,38 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
       return FALSE;
     }
 
-  egl_onscreen->egl_surface = egl_display->egl_surface;
+  if (egl_display->egl_surface == EGL_NO_SURFACE)
+    {
+      egl_onscreen->egl_surface =
+        eglCreateWindowSurface (egl_renderer->edpy,
+                                egl_display->egl_config,
+                                (NativeWindowType) NULL,
+                                NULL);
+      if (egl_onscreen->egl_surface == EGL_NO_SURFACE)
+        {
+          g_set_error (error, COGL_WINSYS_ERROR,
+                       COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                       "Unable to create EGL window surface");
+          return FALSE;
+        }
+    }
+  else
+    egl_onscreen->egl_surface = egl_display->egl_surface;
+
+  eglQuerySurface (egl_renderer->edpy,
+                   egl_onscreen->egl_surface,
+                   EGL_WIDTH,
+                   &egl_surface_width);
+
+  eglQuerySurface (egl_renderer->edpy,
+                   egl_onscreen->egl_surface,
+                   EGL_HEIGHT,
+                   &egl_surface_height);
 
   _cogl_framebuffer_winsys_update_size (framebuffer,
-                                        null_display->egl_surface_width,
-                                        null_display->egl_surface_height);
+                                        egl_surface_width,
+                                        egl_surface_height);
+
   null_display->have_onscreen = TRUE;
 
   return TRUE;
@@ -199,6 +241,16 @@ _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen)
   CoglDisplay *display = context->display;
   CoglDisplayEGL *egl_display = display->winsys;
   CoglDisplayNull *null_display = egl_display->platform;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+  CoglRenderer *renderer = display->renderer;
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+
+  if (egl_onscreen->egl_surface != egl_display->egl_surface &&
+      egl_onscreen->egl_surface != EGL_NO_SURFACE)
+    {
+      eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface);
+      egl_onscreen->egl_surface = EGL_NO_SURFACE;
+    }
 
   null_display->have_onscreen = FALSE;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]