[vlc-commits] [Git][videolan/vlc][master] 5 commits: egl: allow swapping without current context

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat May 7 15:12:28 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
61bb9420 by Alexandre Janniaux at 2022-05-07T14:54:26+00:00
egl: allow swapping without current context

The vlc_gl_t API doesn't require the context to be current to call
vlc_gl_Swap(), but EGL needs it. Allowing vlc_gl_Swap from being called
outside of vlc_gl_MakeCurrent/ReleaseCurrent will allow to remove the
MakeCurrent/ReleaseCurrent mechanism and have the OpenGL provider pull
for a frame rendering instead of the code waiting on draw commands for
OpenGL to be ready to render, which is functionnally the same, but will
allow implementations like macosx.m or caopengllayer.m to be a real
OpenGL implementation instead of dummy provider around a display module.

- - - - -
610c50b1 by Alexandre Janniaux at 2022-05-07T14:54:26+00:00
opengl: display: load glFlush from context

Since the vout display work is splitted between prepare() and display(),
the flush is useful to ensure everything has been submitted by the end
of prepare() so that the result can be used in display().

- - - - -
f058e234 by Alexandre Janniaux at 2022-05-07T14:54:26+00:00
opengl: move vlc_gl_Swap() to display

The display code is better suited to execute Swap() than the
vout_display_opengl object, since:
 - It actually knows whether it's an on-screen or off-screen
   implementation.
 - It could add code to render more things between swapping.
 - In particular, it could render, but discard the rendering instead of
   swapping depending on the time spent or GPU state/chrono.

- - - - -
9b7514f9 by Alexandre Janniaux at 2022-05-07T14:54:26+00:00
opengl: display: move render code to prepare()

Now that we splitted the vlc_gl_Swap() call from the rendering, there's
no excuse for starting rendering sooner so that the result starts to be
available when executing display() and will almost be ready for
presentation.

is_dirty is there to indicate whether vlc_gl_MakeCurrent failed and thus
the frame could not be rendered, to avoid swapping undefined content.

- - - - -
32819382 by Alexandre Janniaux at 2022-05-07T14:54:26+00:00
opengl: vout_helper: remove obsolete comment

vout_display_opengl code has separate prepare() and display(), which
might or might not match vout_display's prepare()/display() calls, now
that the opengl swap() is not done by the vout_display_opengl code.

- - - - -


6 changed files:

- modules/video_output/caopengllayer.m
- modules/video_output/macosx.m
- modules/video_output/opengl/display.c
- modules/video_output/opengl/egl.c
- modules/video_output/opengl/vout_helper.c
- modules/video_output/win32/glwin32.c


Changes:

=====================================
modules/video_output/caopengllayer.m
=====================================
@@ -906,6 +906,7 @@ shouldInheritContentsScale:(CGFloat)newScale
 
         vout_display_opengl_Display(sys->vgl);
         vlc_gl_ReleaseCurrent(sys->gl);
+        vlc_gl_Swap(sys->gl);
     }
 }
 


=====================================
modules/video_output/macosx.m
=====================================
@@ -319,6 +319,7 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic)
         {
             [sys->glView render];
             vlc_gl_ReleaseCurrent(sys->gl);
+            vlc_gl_Swap(sys->gl);
         }
         [sys->glView setVoutFlushing:NO];
     }
@@ -569,6 +570,7 @@ static void OpenglSwap (vlc_gl_t *gl)
         vout_display_opengl_Display (sys->vgl);
     else
         glClear (GL_COLOR_BUFFER_BIT);
+    vlc_gl_Swap(sys->gl);
 }
 
 /**
@@ -621,6 +623,7 @@ static void OpenglSwap (vlc_gl_t *gl)
             return;
 
         [self render];
+        [[self openGLContext] flushBuffer];
         [self unlockgl];
     }
 }


=====================================
modules/video_output/opengl/display.c
=====================================
@@ -77,6 +77,11 @@ typedef struct vout_display_sys_t
     vlc_gl_t *gl;
     vout_display_place_t place;
     bool place_changed;
+    bool is_dirty;
+
+    struct {
+        PFNGLFLUSHPROC Flush;
+    } vt;
 } vout_display_sys_t;
 
 /* Display callbacks */
@@ -119,6 +124,7 @@ static int Open(vout_display_t *vd,
         return VLC_ENOMEM;
 
     sys->gl = NULL;
+    sys->is_dirty = false;
 
     vout_window_t *surface = vd->cfg->window;
     char *gl_name = var_InheritString(surface, MODULE_VARNAME);
@@ -154,6 +160,9 @@ static int Open(vout_display_t *vd,
     if (sys->gl == NULL)
         goto error;
 
+    sys->vt.Flush = vlc_gl_GetProcAddress(sys->gl, "glFlush");
+    if (sys->vt.Flush == NULL)
+        goto error;
 
     vout_display_cfg_t flipped_cfg = *vd->cfg;
     FlipVerticalAlign(&flipped_cfg);
@@ -211,17 +220,7 @@ static void PictureRender (vout_display_t *vd, picture_t *pic, subpicture_t *sub
     if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
     {
         vout_display_opengl_Prepare (sys->vgl, pic, subpicture);
-        vlc_gl_ReleaseCurrent (sys->gl);
-    }
-}
-
-static void PictureDisplay (vout_display_t *vd, picture_t *pic)
-{
-    vout_display_sys_t *sys = vd->sys;
-    VLC_UNUSED(pic);
-
-    if (vlc_gl_MakeCurrent (sys->gl) == VLC_SUCCESS)
-    {
+        sys->vt.Flush();
         if (sys->place_changed)
         {
             vout_display_opengl_SetOutputSize(sys->vgl, sys->place.width,
@@ -230,12 +229,23 @@ static void PictureDisplay (vout_display_t *vd, picture_t *pic)
                                          sys->place.width, sys->place.height);
             sys->place_changed = false;
         }
-
         vout_display_opengl_Display(sys->vgl);
+        sys->vt.Flush();
         vlc_gl_ReleaseCurrent (sys->gl);
+        sys->is_dirty = true;
     }
 }
 
+static void PictureDisplay (vout_display_t *vd, picture_t *pic)
+{
+    vout_display_sys_t *sys = vd->sys;
+    VLC_UNUSED(pic);
+
+    /* Present on screen */
+    if (sys->is_dirty)
+        vlc_gl_Swap(sys->gl);
+}
+
 static int Control (vout_display_t *vd, int query)
 {
     vout_display_sys_t *sys = vd->sys;


=====================================
modules/video_output/opengl/egl.c
=====================================
@@ -63,6 +63,7 @@ typedef struct vlc_gl_sys_t
 #if defined (USE_PLATFORM_WAYLAND)
     struct wl_egl_window *window;
 #endif
+    bool is_current;
 } vlc_gl_sys_t;
 
 static int MakeCurrent (vlc_gl_t *gl)
@@ -72,6 +73,7 @@ static int MakeCurrent (vlc_gl_t *gl)
     if (eglMakeCurrent (sys->display, sys->surface, sys->surface,
                         sys->context) != EGL_TRUE)
         return VLC_EGENERIC;
+    sys->is_current = true;
     return VLC_SUCCESS;
 }
 
@@ -81,6 +83,7 @@ static void ReleaseCurrent (vlc_gl_t *gl)
 
     eglMakeCurrent (sys->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                     EGL_NO_CONTEXT);
+    sys->is_current = false;
 }
 
 #ifdef USE_PLATFORM_XCB
@@ -112,7 +115,18 @@ static void SwapBuffers (vlc_gl_t *gl)
 {
     vlc_gl_sys_t *sys = gl->sys;
 
-    eglSwapBuffers (sys->display, sys->surface);
+    if (!sys->is_current)
+    {
+        EGLSurface s_read = eglGetCurrentSurface(EGL_READ);
+        EGLSurface s_draw = eglGetCurrentSurface(EGL_DRAW);
+        EGLContext previous_context = eglGetCurrentContext();
+
+        eglMakeCurrent(sys->display, sys->surface, sys->surface, sys->context);
+        eglSwapBuffers (sys->display, sys->surface);
+        eglMakeCurrent(sys->display, s_read, s_draw, previous_context);
+    }
+    else
+        eglSwapBuffers (sys->display, sys->surface);
 }
 
 static void *GetSymbol(vlc_gl_t *gl, const char *procname)
@@ -234,6 +248,7 @@ static int Open(vlc_gl_t *gl, const struct gl_api *api,
     sys->display = EGL_NO_DISPLAY;
     sys->surface = EGL_NO_SURFACE;
     sys->context = EGL_NO_CONTEXT;
+    sys->is_current = false;
 
     vout_window_t *wnd = gl->surface;
     EGLSurface (*createSurface)(EGLDisplay, EGLConfig, void *, const EGLint *)


=====================================
modules/video_output/opengl/vout_helper.c
=====================================
@@ -314,10 +314,6 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl)
 {
     GL_ASSERT_NOERROR(&vgl->api.vt);
 
-    /* Why drawing here and not in Render()? Because this way, the
-       OpenGL providers can call vout_display_opengl_Display to force redraw.
-       Currently, the OS X provider uses it to get a smooth window resizing */
-
     int ret = vlc_gl_filters_Draw(vgl->filters);
     if (ret != VLC_SUCCESS)
         return ret;
@@ -326,9 +322,6 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl)
     if (ret != VLC_SUCCESS)
         return ret;
 
-    /* Display */
-    vlc_gl_Swap(vgl->gl);
-
     GL_ASSERT_NOERROR(&vgl->api.vt);
 
     return VLC_SUCCESS;


=====================================
modules/video_output/win32/glwin32.c
=====================================
@@ -247,5 +247,6 @@ static void Display(vout_display_t *vd, picture_t *picture)
     {
         vout_display_opengl_Display(sys->vgl);
         vlc_gl_ReleaseCurrent (sys->gl);
+        vlc_gl_Swap(sys->gl);
     }
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ad4cb3ac56d35de24edad0ba88db7e6910abeb61...32819382024f80a220f287915f979c16a58f0f3d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ad4cb3ac56d35de24edad0ba88db7e6910abeb61...32819382024f80a220f287915f979c16a58f0f3d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list