1. 22 Jul, 2021 40 commits
    • Matthias Clasen's avatar
      Add more sysprof marks · a10b1b73
      Matthias Clasen authored
      Add a few more marks during gtk_init to figure out where
      our startup time goes, and avoid the sysprof initialization
      from distorting the first mark.
      a10b1b73
    • Benjamin Otte's avatar
      Merge branch 'wip/otte/gleanup' into 'master' · 02c62267
      Benjamin Otte authored
      reorganize GDK's GL code
      
      See merge request !3726
      02c62267
    • Benjamin Otte's avatar
      glx: Get rid fo DrawableInfo · 620ccdab
      Benjamin Otte authored
      Store the frame counter in the surface, where it belongs.
      620ccdab
    • Chun-wei Fan's avatar
      gdkdisplay-win32.c: Don't call ReleaseDC() unnecessarily · 4b12dc65
      Chun-wei Fan authored
      The dummy Win32 window that we use to capture display change events and
      to create dummy WGL contexts was created with CS_OWNDC, so we really do
      not need to (and should not) call ReleaseDC() on the HDC that we
      obtained from it, so drop these calls.
      4b12dc65
    • Chun-wei Fan's avatar
      GDK-Win32: init_gl(): Default to WGL for now · bd69d7e2
      Chun-wei Fan authored
      Since the shaders need to be updated for using with GLES (libANGLE at
      least), default to WGL for now.  Unfortunately it is not that common for
      Windows to have GLES support, in which the easiest way to obtain such
      support is via Google's libANGLE.
      bd69d7e2
    • Chun-wei Fan's avatar
      GDK-Win32: Fixup, and cleanup WGL HDC handling · 86484864
      Chun-wei Fan authored
      It turns out that the problem of the WGL window not drawing was due to
      the fact that I messed up where I placed SwapBuffers() during the
      conversion... doh:|
      
      At the same time, stop storing the HDC in the GdkWin32GLContextWGL, but
      instead always create it along the surface we created, so that it is ready
      for use for operating with WGL when we are not dealing with "surfaceless"
      contexts.  If we are dealing with "surfaceless" contexts, just use the
      HDC of the dummy window that we created when we created the
      Gdk(Win32)Display.
      
      WGL contexts should now be in working order at this point.
      86484864
    • Chun-wei Fan's avatar
      Split out WGL/EGL stuff and simplify things · 6c001171
      Chun-wei Fan authored
      This commit attempts to split GdkWin32GLContext into two parts, one for
      WGL and the other for EGL (ANGLE), and attempts to simplify things a
      bit, by:
      
      *  We are already creating a Win32 window to capture display changes,
         so we can just use that to act as our dummy window that we use to
         find out the pixel format that the system supports for WGL.  We also
         use it to obtain the dummy legacy WGL context that we will always
         require to create our more advanced Core WGL contexts.
      
      *  Like what is done in X11, store up the WGL pixel format or the
         EGLConfig in our GdkWin32Display.
      
      *  Ensure we do not create the dummy WGL context unnecessarily.
      
      In this way, we can successfully create the WGL/EGL contexts, however
      there are some issues at this point:
      
      *  For WGL, the code successfully initializes and realizes the WGL
         Contexts, but for some reason things became invisible.  When running
         gtk4-demo, this can be verified by seeing the mouse cursor changing
         when moved to spots where one can resize the window, although they
         were invisible.
      
      *  For EGL, the code initializes EGL but could not realize the EGL
         context as shaders failed to compile.  It seems like the shader issue
         is definitely outside the scope of this MR.
      6c001171
    • Benjamin Otte's avatar
      gl: Fix issue with EGL + nvidia · 9c4c4eaa
      Benjamin Otte authored
      nvidia sets the default draw buffer to GL_NONE if EGL contexts are
      initially bound to EGL_NO_SURFACE which is exactly what we are doing. So
      bind them to GL_BACK when drawing, as they should be.
      
      See https://phabricator.services.mozilla.com/D118743 for a discussion
      about EGL_NO_CONTEXT and draw buffers.
      9c4c4eaa
    • Chun-wei Fan's avatar
      GDK: Add debug option for WGL usage · 969b3257
      Chun-wei Fan authored
      This way, one can force using WGL on Windows even if EGL support was
      enabled.  Also update the help text for gl-egl as it will apply for
      Windows, albeit a bit later.
      969b3257
    • Chun-wei Fan's avatar
      GDK-Win32: Move some functions out of gdkglcontext-win32.c · 65c6af31
      Chun-wei Fan authored
      We want these to be out of the way as we split between WGL and EGL/ANGLE
      GL contexts, so that they don't get in the way.
      65c6af31
    • Benjamin Otte's avatar
      display: Move GL selection code into gdkdisplay-x11.c · 6b8bc834
      Benjamin Otte authored
      This has the benefit that we can refactor it and make sure we deal with
      GdkDisplay::init_gl() not being called at all because
      GDK_DEBUG=gl-disable had been specified.
      6b8bc834
    • Benjamin Otte's avatar
      x11: Move code from GdkGLContextX11 · 30aaab5c
      Benjamin Otte authored
      It's not used there, but both backends have independent
      immplementationgs for it.
      
      I want to get rid of GdkGLContextX11 and moving code from it is the
      first step.
      30aaab5c
    • Benjamin Otte's avatar
      inspector: Add support for displaying GL errors · 72e2a46c
      Benjamin Otte authored
      Also, no need to show a GL version if GL isn't available.
      72e2a46c
    • Benjamin Otte's avatar
      gdk: Move GL context construction to GdkGLContext · e06e0e85
      Benjamin Otte authored
      Now that we have the display's context to hook into, we can use it to
      construct other GL contexts and don't need a GdkSurface vfunc anymore.
      
      This has the added benefit that backends can have different GdkGLContext
      classes on the display and get new GLContexts generated from them, so
      we get multiple GL backend support per GDK backend for free.
      
      I originally wanted to make this a vfunc on GdkGLContextClass, but
      it turns out all the abckends would just call g_object_new() anyway.
      e06e0e85
    • Benjamin Otte's avatar
      gl: Move vfunc · 9f1d6e1f
      Benjamin Otte authored
      Instead of
        Display::make_gl_context_current()
      we now have
        GLContext::clear_current()
        GLContext::make_current()
      
      This fits better with the backends (we can actually implement
      clearCurrent on macOS now) and makes it easier to implement different GL
      backends for backends (like EGL/GLX on X11).
      
      We also pass a surfaceless boolean to make_current() so the calling code
      can decide if a surface needs to be bound or not, because the backends
      were all doing whatever, which was very counterproductive.
      9f1d6e1f
    • Benjamin Otte's avatar
      gl: Require EGL_KHR_surfaceless_context with egl · 15ed1a32
      Benjamin Otte authored
      The code to create and manage a fake egl surface to bind to is
      complex and completely untested because everyone seems to support this
      extension.
      
      nvidia and Mesa do support it and according to Mesa devs, adding support
      in a new driver is rather simple and Mesa drivers gain that feature
      automatically, so all future drivers shoould have it.
      15ed1a32
    • Benjamin Otte's avatar
      gdk: Get rid of paint contexts · 50543634
      Benjamin Otte authored
      ... or more exactly: Only use paint contexts with
      gdk_cairo_draw_from_gl().
      
      Instead of paint contexts being the only contexts who call swapBuffer(),
      any context can be used for this, when it's used with
      begin_frame()/end_frame().
      
      This removes 2 features:
      
      1. We no longer need a big sharing hierarchy. All contexts are now
         shared with gdk_display_get_gl_context().
      2. There is no longer a difference between attached and non-attached
         contexts. All contexts work the same way.
      50543634
    • Benjamin Otte's avatar
      gl: Store the context::in-frame state in the current context · a27434a8
      Benjamin Otte authored
      Do not treat the context as already current when the value
      of context::in-frame changes.
      
      This is so we can bind to EGL_NO_SURFACE if context::in-frame == false
      and to context::surface if context::in-frame == true.
      
      This allows getting rid of the attached property in future commits.
      a27434a8
    • Benjamin Otte's avatar
      gl: Deprecate gdk_gl_context_get_shared_context() · 2c987861
      Benjamin Otte authored
      It's not used anymore. And in particular we do want to keep the display
      context private, so we're not gonna return it from this function.
      2c987861
    • Benjamin Otte's avatar
      gdk: Add gdk_gl_context_is_shared() · c7320df0
      Benjamin Otte authored
      ... and use it in the GL renderers.
      c7320df0
    • Benjamin Otte's avatar
      ngl: Store the shared driver in the display · dd666e4f
      Benjamin Otte authored
      ... instead of some random GL context.
      dd666e4f
    • Benjamin Otte's avatar
      gdk: Require EGL version 1.4 across the board · e4f04180
      Benjamin Otte authored
      Mesa currently ships 1.5.
      e4f04180
    • Benjamin Otte's avatar
      gdk: Add GdkDisplay::init_gl vfunc · 430b6f8f
      Benjamin Otte authored
      The vfunc is called to initialize GL and it returns a "base" context
      that GDK then uses as the context all others are shared with. So the GL
      context share tree now looks like:
      
      + context from init_gl
        - context1
        - context2
        ...
      
      So this is a flat tree now, the complexity is gone.
      
      The only caveat is that backends now need to create a GL context when
      initializing GL so some refactoring was needed.
      
      Two new functions have been added:
      
      * gdk_display_prepare_gl()
        This is public API and can be used to ensure that GL has been
        initialized or if not, retrieve an error to display (or debug-print).
      * gdk_display_get_gl_context()
        This is a private function to retrieve the base context from
        init_gl(). It replaces gdk_surface_get_shared_data_context().
      430b6f8f
    • Benjamin Otte's avatar
      wayland: Don't pass GL config to get_egl_surface() · ba3e80cb
      Benjamin Otte authored
      There's only one GL config.
      ba3e80cb
    • Benjamin Otte's avatar
      wayland: Move fbconfig into the display · 7cd4282b
      Benjamin Otte authored
      Create it during init and then reuse it for all contexts.
      
      While doing that, also improve error reporting - that's not used yet but
      will in later commits.
      7cd4282b
    • Benjamin Otte's avatar
      gdk: Allow GdkDrawContext with a %NULL surface · 01e9fa9a
      Benjamin Otte authored
      This is not used yet, but it allows surfaceless GL contexts.
      
      For that purpose, we need to make the display a construct-only property,
      so that it can be set when the surface isn't.
      
      This adds a bunch of very picky checks in the constructor so nothing bad
      can happen.
      01e9fa9a
    • Benjamin Otte's avatar
      gdk: Add a private struct to GdkDisplay · 581e01b2
      Benjamin Otte authored
      ... and move some members from the GdkDisplay struct.
      
      We've always wanted to add one to isolate the display from the backends
      a bit more, but so far it's never happened.
      
      Now that I'm about to add more data to GdkDisplay, it's a good excuse to
      start.
      581e01b2
    • Benjamin Otte's avatar
      x11: Redo choice between EGL and GLX · 5a3b4de1
      Benjamin Otte authored
      We try EGL first, but are very picky about what we accept.
      If that fails, we try to go with GLX instead.
      And if that also fails, we try EGL again, but this time accept anything.
      
      The idea here is that EGL is the preferred method going forward, but GLX is
      the tried and tested method that we know works. So if we detect issues with
      EGL, we want to avoid using it in favor of GLX.
      
      Also add a GDK_DEBUG=gl-egl option to force EGL at all costs and not try
      GLX.
      5a3b4de1
    • Benjamin Otte's avatar
      x11: Properly record the error when initializing GL · 74288ece
      Benjamin Otte authored
      That way, we can give a useful error message when things break down for
      users.
      
      These error messages could still be improved in places (like looking at
      the actual EGL error codes), but that seemed overkill.
      74288ece
    • Benjamin Otte's avatar
      x11: Do not call glXQueryExtension() · 37ba0571
      Benjamin Otte authored
      epoxy does that already.
      37ba0571
    • Benjamin Otte's avatar
      x11: Get Visual from EGL directly · 6d5ba959
      Benjamin Otte authored
      Query the EGL_VISUAL_ID from the egl Config and select a config with the
      matching Visual.
      
      This is currently broken on Mesa because it does not expose any RGBA
      X Visuals in any EGL config, so we always end up with opaque Windows.
      
      https://gitlab.freedesktop.org/mesa/mesa/-/issues/149
      6d5ba959
    • Benjamin Otte's avatar
      x11: Store the GLX drawable in the surface · 215f7928
      Benjamin Otte authored
      Also, stop using a dummy window for unattached GL contexts and instead
      use the display's leader surface.
      
      Again, this mirrors EGL.
      215f7928
    • Benjamin Otte's avatar
      x11: Use single GLX fbconfig and store it in the display · 1c55b328
      Benjamin Otte authored
      This mirrors the code for the EGL config.
      1c55b328
    • Benjamin Otte's avatar
      x11: Remove glx version check · 82eb947f
      Benjamin Otte authored
      We only work with GLX >= 1.3 anyway, so don't explicitly check for it
      and pretend to do something else that doesn't work otherwise.
      82eb947f
    • Benjamin Otte's avatar
      x11: Remove unused struct member · 485dae9f
      Benjamin Otte authored
      We don't care if the GL context is direct at all.
      485dae9f
    • Benjamin Otte's avatar
      Revert "x11: Always fall back to GLX on NVIDIA" · eb342331
      Benjamin Otte authored
      This reverts commit c35a6725.
      
      This approach doesn't work because if NVIDIA doesn't work for EGL, the
      EGL implementation won't be provided by NVIDIA, so checking the vendor
      doesn't work.
      eb342331
    • Benjamin Otte's avatar
      x11: Remove the dummy surface · 04c2093d
      Benjamin Otte authored
      Instead, use the display's "leader surface" when no surface is required,
      because we have it lying around.
      
      Really, we want to use EGL_NO_SURFACE, but if that's not supported...
      04c2093d
    • Benjamin Otte's avatar
      x11: Remove GdkVisual · ccd5992a
      Benjamin Otte authored
      It's not used anymore.
      ccd5992a
    • Benjamin Otte's avatar
      x11: Rework Visual selection · ca8d9fbe
      Benjamin Otte authored
      Instead of going via GdkVisual, doing a preselection and letting the GL
      initialization improve it, let the GL initialization pick an X Visual
      directly using X Visual code directly.
      
      The code should select the same visuals as before as it tries to apply
      the same logic, but it's a rewrite, so I expect I messed something up.
      ca8d9fbe
    • Benjamin Otte's avatar
      glx: Remove Visual cache · 62bac44a
      Benjamin Otte authored
      1. We're using EGL most of the time anyway, so if we wanted to cache
         things, we'd need to port it there.
      2. Our GL handling is massively configurable, so determining when to use
         the cache and when not is a challenge.
      3. It makes startup nondeterministic and depend on whether a GTK4 app
         has previously been started on this display and nobody thinks about
         that when debugging.
      4. The only benefit of the caching is delaying GL initialization - which
         made sense in GTK3 where almost no app used GL but doesn't make sense
         in GTK4 where almost every app uses GL.
      
      So unless I find a big benefit to reintroducing it, this cache will be
      gone for good.
      62bac44a