Commit Graph

54 Commits

Author SHA1 Message Date
Luca Bacci
0fcdadc531 GdkWin32GLContextWGL: Use the previous frames paint regions kept by GdkGLContext
We do this because:

 a) The parent class (GdkGLContext) already stores the paint regions of
    previous frames, no need to do the same.
 b) The painted region passed to end_frame () includes the backbuffer's
    damage region, so it's not really what we want.

This also fixes a leak of cairo_region_t that I introduced by mistake
in !7418
2024-08-26 17:05:13 +02:00
Luca Bacci
d3e3ddf897 WGL: Report paint region when presenting (SwapBuffers)
Report the paint region to the OpenGL driver, which in turn may
report it to the system compositor (DWM).
2024-08-12 18:56:45 +02:00
Luca Bacci
fca983e81e WGL: Report backbuffer's damage to GDK
The backbuffer's damage region is the region of the backbuffer
that doesn't contain up-to-date contents. This is determined
by the backbuffer's age and previous frame's paint regions.

This enables incremental rendering
2024-08-12 18:56:34 +02:00
Luca Bacci
41b21b6634 WGL: Search pixel format with defined swap method (opengl32)
We want to get PFD_SWAP flags as that's required to enable incremental
rendering. However, as documented on MSDN, ChoosePixelFormat ignores
PFD_SWAP flags.

We may get PFD_SWAP flags or not depending on the way the OpenGL driver
orders its pixel formats. While PFD_SWAP flags are very important for
GUI toolkits, they are best avoided by games, as most games render the
scene in its entirety on each frame. Drivers optimized for games tend
to order pixel formats with no PFD_SWAP flags first.

Se we implement our own method to select the best pixel format. We check
for usable pixel formats and assign penalties for each one, until we find
a format with 0 penalty or the sequence ends. Then the best pixel format
is selected.
2024-07-24 15:36:25 +02:00
Luca Bacci
b46a900d71 WGL: Search pixel format with defined swap method (arb)
Getting a defined swap method is necessary to enable incremental
rendering. We cannot just add a swap method attribute since
exchange is generally preferred, but is not always available.
Here we try to infer what the driver prefers, then ask for
exchange or copy, in sequence.
2024-07-24 15:35:40 +02:00
Benjamin Otte
1b1e7f4296 drawcontext: Make begin_frame() set colorstate + depth
Make begin_frame() set a rendering colorstate and depth, and provide it
to the renderers via gdk_draw_context_get_depth() and
gdk_draw_context_get_color_state().

This allows the draw contexts to define their own values, so that ie the
Cairo and GL renderer can choose different settings for rendering (in
particular, GL can choose GL_SRGB and do the srgb conversion; while
Cairo relies on the renderer).
2024-07-11 14:57:20 +02:00
Matthias Clasen
8841a002ed Merge branch 'build-with-unicode' into 'main'
Windows: Build with UNICODE

See merge request GNOME/gtk!7230
2024-05-29 23:20:01 +00:00
Matthias Clasen
6da606aaad Merge branch 'issue-6401-legacy' into 'main'
Win32 GL: Also force not to use depth/stencil/accum bits on legacy contexts (for issue #6401)

See merge request GNOME/gtk!7176
2024-05-29 23:18:04 +00:00
Luca Bacci
7f9363d471 Windows: Build with UNICODE
Build with UNICODE (and _UNICODE) defined when targeting Windows.
2024-05-28 16:37:48 +02:00
Georges Basile Stavracas Neto
45e64b915c win32/wgl: Initialize hwnd to NULL
Otherwise there's a valid code path that may return it uninitialized.
2024-05-03 09:51:46 -03:00
Chun-wei Fan
54a86a2a7e Win32 GL: Also force not to use depth/stencil/accum bits on legacy contexts
For completeness' sake, also specifiy in the PIXELFORMATDESCRIPTOR to use no
depth, stencil and accum bits to initializing WGL when we can't (yet) use
wglChoosePixelFormatARB(), as we must always fist have a base legacy WGL
context using ChoosePixelFormat() before we can use that to use
wglChoosePixelFormatARB(), or if wglChoosePixelFormatARB() is somehow not
available for us.

Some drivers, however, enforces enabling depth buffers, so if we can't
acquire a pixel format that disables depth buffers, retry acquiring one
with that, which sadly is not optimal but we must make do.

Attempts to complete fix for issue #6401.
2024-04-24 16:23:17 +08:00
Luca Bacci
73e8b39bc6 WGL: Initialize PIXELFORMATDESCRIPTOR structure 2024-02-19 18:16:35 +01:00
Luca Bacci
72b2938e43 WGL: Request that no depth, stencil and accum buffers be created
Unspecified attributes are not interpreted as "leave this feature out",
rather as "pick a default value". For depth, stencil and accum bits the
defaults may be different than 0. For example, with AMD drivers we get:

 * WGL_DEPTH_BITS_ARB:   32
 * WGL_STENCIL_BITS_ARB: 8
 * WGL_ACCUM_BITS_ARB:   0

Set the attributes to 0 as a hint that depth, stencil and accum buffers
should not be created.

The driver may still create them (matching criteria is "minimum" [1]),
but that's outside of our control (and unlikely to happen).

References:

 [1] - WGL_ARB_pixel_format specification
       https://registry.khronos.org/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt

See #6401
2024-02-19 18:15:52 +01:00
Luca Bacci
57dde7e877 GdkWin32: Implement GdkDrawContext::empty_frame() vfunc 2024-01-30 16:23:28 +01:00
Luca Bacci
4e5456c8c3 GdkWin32: Do not create multiple WGL contexts for the dummy window
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/6285
2023-12-27 16:26:06 +01:00
Matthias Clasen
f04c819439 Drop the gl-legacy debug value
The consensus is that we can do without this.
2023-11-20 08:02:02 -05:00
Benjamin Otte
310ab7b531 Remove G_ENABLE_DEBUG around debug checks
It started out as busywork, but it does many separate things. If I could
start over, I'd take them apart into multiple commits:

1. Remove G_ENABLE_DEBUG around GDK_DEBUG_*() calls
   This is not needed at all, the calls themselves take care of it.

2. Remove G_ENABLE_DEBUG around profiling code
   This now enables profiling support in release builds.

3. Stop poking _gdk_debug_flags and use GDK_DEBUG_CHECK()
   This was old code that was never updated.

4. Make !G_ENABLE_DEBUG turn off GDK_DEBUG_CHECK()
   The code used to
     #define GDK_DEBUG_CHECK(...) false
     #define GDK_DEBUG(...)
   which would compile away all the code inside those macros. This
   means a lot of variable definitions and debug utility functions
   would suddenly no longer be used and cause compiler errors.
2023-11-05 11:16:23 +01:00
Benjamin Otte
090cd2238a gdk: Replace prefers_high_depth with depth
Now that we track depth, we can also pass it into the GDK frame code.

For now it's just passed along, code acts the same as with
prefers_high_depth.
2023-06-18 14:28:39 +02:00
Luca Bacci
1a058a41c9 Do not keep HINSTANCE variables around
Use &__ImageBase for the GTK DLL and GetModuleHandle (NULL)
for the application module. Then remove DllMain as it's not
necessary anymore.

References:

 [1] Accessing the current module's HINSTANCE from a static library:
     https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
2023-05-30 19:31:54 +02:00
Chun-wei Fan
0073ee29da gdkglcontext-win32-wgl.c: Always request alpha bits
...when we are using wglChoosePixelFormatARHB().  This ensures that we
hvae a HDC with a pixel format that will really support alpha bits, as
we did for the traditional ChoosePixelFormat().

Thanks to Patrick Zacharias for testing and pointing things out.
2023-05-09 18:15:23 +08:00
Benjamin Otte
e9ed5e21ef win32: Turn off multisampling
We know we draw beautiful Windows, but drawing them once is totally
enough.
2023-05-09 18:15:23 +08:00
Benjamin Otte
c37786af36 win32: Actually increase the counter
We were sending random junk to ChoosePixelFormat().

Also assert that we don't overflow the array. That might be usefu to
know if we carelessly add attributes later.
2023-05-09 18:15:23 +08:00
Chun-wei Fan
a7b09e19f1 GDK/Win32: Use dummy WGL contexts more
... for creating the actual WGL contexts, so that we can cut down on the
number of times where we need to create the base, legacy WGL contexts in
order to create the WGL contexts with attributes.  We could just use the
dummy context that we have to make it current to create the needed
WGL contexts.
2023-05-09 18:15:23 +08:00
Chun-wei Fan
50ef36d387 gdkglcontext-win32-wgl.c: Fix using wglChoosePixelFormatARB()
If we are querying the best supported pixel format for our HDC via
wglChoosePixelFormatARB() (i.e. we have the WGL_ARB_pixel_format extension),
it may return a pixel format that is different from the pixel format that we
used for the dummy context that we have setup, in order to, well, run
wglChoosePixelFormatARB(), which sadly requires a WGL context (HGLRC) to be
current in order to use it, which means the dummy HDC already has a pixel
format that has been set (notice that each HDC is only allowed to have its
pixel format to be set *once*). This is notably the case on Intel display
drivers.

Since we are emulating surfaceless GL contexts, we are using the dummy GL
context (and thus dummy HDC that is derived from the notification HWND used in
GdkWin32Display) for doing that, we would get into trouble if th actual HDC
from the GdkWin32Surface has a different pixel format set.

So, as a result, in order to fix this situation, we do the following:

* Create yet another dummy HWND in order to grab the HDC to query for the
  capabilities the GL drivers support, and to call wglChoosePixelFormatARB() as
  appropriate (or ChoosePixelFormat()) for the final pixel format that we use.
* Ditch the dummy GL context, HDC and HWND after obtaining the pixel format.
* Then set the final pixel format that we obtained onto the HDC that is derived
  from the HWND used in GdkWin32Display for notifications, which will become our
  new dummy HDC.
* Create a new dummy HGLRC for use with the new dummy HDC to emulate surfaceless
  GL support.
2023-05-09 18:15:23 +08:00
Chun-wei Fan
d02ae09124 gdkglcontext-win32-wgl.c: Fix WGL context realization on 32-bit
We are currently using g_clear_pointer() on the intermediate WGL contexts
(HGLRC)'s that we need to create in the way, which means that we need to ensure
that the correct calling convention for wglDeleteContext() is being applied.

To be absolutely safe about it, use the gdk_win32_private_wglDeleteContext()
calls, which will in turn call wglDeleteContext() directly from opengl32.dll
(using the OpenGL headers from the Windows SDK) instead of going via libepoxy,
which will assure us that the correct calling convention is applied.

Fixes issue #5808.
2023-05-09 11:47:28 +08:00
Benjamin Otte
9254ab8503 wgl: Improve error messages when GL init fails
In particular, we want to get the GL version, when the Windows box/VM
has an unsuitable GL implementation.

This is somewhat helpful in analyzing failures to bring up GL on
machines where users claim GL does work.
2023-04-27 02:19:25 +02:00
Benjamin Otte
d6afcee1e4 wgl: Create context during WGL initialization
This way, we can realize it and either print success information about
it or return NULL if that fails.

This makes it more likely that we fail early, which means we can then
initialize EGL.
2023-04-27 02:16:46 +02:00
Benjamin Otte
c71ca481c1 win32: Get rid of display->gl_version
We can just query the display's GL context.

And it's not used otherwise anymore.
2023-04-27 02:13:33 +02:00
Benjamin Otte
8ef38c46b5 win32: Refactor context creation
This refactor achieves the following:

 * check GL version against proper matching context version
   In particular, for legacy contexts, we now actually check
 * make sure the actual version is set, even for legacy contexts
 * make sure set_is_legacy() is set properly
2023-04-27 02:13:33 +02:00
Benjamin Otte
5f833f1d31 glcontext: Compute matching version the simple way
Do it all in one function instead of requiring two different ones.
2023-04-27 02:13:32 +02:00
Benjamin Otte
b8958419e6 win32: Make sure highest possible GL version is created
Mirror EGL here.
2023-04-27 02:13:32 +02:00
Benjamin Otte
919c90182f win32: Pass the version properly through the creation stack
We were using major/minor instead of GdkGLVersion.

And we were resetting back to 0 and ignoring the required min version
which we should not do.
2023-04-27 02:13:32 +02:00
Benjamin Otte
f86429177a gdk: Introduce GdkGLVersion
... and use it.

Makes the code simpler.
2023-04-27 02:13:32 +02:00
Benjamin Otte
dacfed3e11 win32: Remove an outdated check
We require GL 3.0, so checking for less than 2.0 makes no sense anymore.
2023-04-27 02:13:32 +02:00
Chun-wei Fan
627ee674e5 GDK-Win32: Add wrapper functions for calling core wgl* functions
We might be dealing with GL contexts from different threads, which have more
gotchas when we are using libepoxy, so in case the function pointers for
these are invalidated by wglMakeCurrent() calls outside of GTK/GDK, such as
in GstGL, we want to use these functions that are directly linked to
opengl32.dll provided by the system/ICD, by linking to opengl32.lib.

This will ensure that we will indeed call the "correct" wgl* functions that
we need.

This should help fix issue #5685.
2023-03-24 18:43:23 +08:00
Benjamin Otte
c6cef6db52 gdk: Add private GLContext::is_current() check
... and use this check in gdk_gl_context_make_current() and
gdk_gl_context_get_current() to make sure the context really is still
current.

The context no longer being current can happen when external GL
implementations make their own contexts current in the same threads GDK
contexts are used in.
And that can happen for example by WebKit.

Theoretically, this should also allow external EGL code to run in X11
applications when GDK chooses to use GLX, but I didn't try it.

Fixes #5392
2023-02-02 04:23:51 +01:00
Matthias Clasen
4aabc45685 Drop gdkintl.h
This header was merely including gi18n-lib.h.
Just do that directly.
2022-09-23 23:33:42 -04:00
Matthias Clasen
8bd3ec2ba1 Make the gl-legacy debug flag always available
No need to restrict this to debug builds.
2022-09-21 21:09:08 -04:00
Pablo Correa Gómez
d4f8a80f2a
glcontext-win32-wgl: Respect user required version, use display as minimum
By setting and then getting the required version in a context, the code
was not respecting user requirements. Instead, simply get the requested
version by the user clipped by the requirements (display version)
2022-06-04 20:48:40 +02:00
Chun-wei Fan
6f2848c311 Cleanup "GDK/Win32: Try to fix initializing GLES contexts"
As per Benjamin's suggestions, cleanup the previous implementation on
initializing the GLES context on Windows, so that we use more items that are
already in GDK proper and integrate two functions into one.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
38c17c1f79 gdkglcontext-win32-wgl.c: Cleanup GL context creation
Instead of first trying to explicitly ask for a WGL 4.1 context, ask for
the WGL context version that matches what is reported via
epoxy_gl_version(), so that we get the maximum WGL version that is
supported by the graphics drivers, and make sure any WGL contexts that
are shared with this (initial) WGL context are created likewise.

We can try to do a default-bog-standard 3.2 core WGL context creation
if the need arises, but let's leave that alone for now.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
598c7d9cf4 GDK/Win32: Try to fix initializing GLES contexts
We are now able to create EGL contexts properly on Windows, but not GLES.  This
tries to fix things by doing the following:

*  Record the GL context type in a more proper fashion, using an Enum.  This
   makes things a bit cleaner.
*  Force GLES-3.0+ contexts, since libANGLE requires this to properly work with
   the shaders-its 2.0 contexts don't work well with our shaders.
2022-01-19 11:56:32 +08:00
Chun-wei Fan
048fe84888 GDK-Win32: Port to common EGL handling code
This will port the EGL code in GDK-Win32 to use the common GDK code to
initialize EGL.  However, at the current state, although EGL is
correctly initialized, this code is disabled for now since
gdk_gl_context_make_current() fails as the shaders do not work for EGL
via libANGLE on Windows.

We can now clean things up in gdkglcontext-win32-egl.c as a result.
2021-11-08 15:25:24 +08:00
Benjamin Otte
f584d4f500 gl: Check allowed APIs in realize()
Add gdk_gl_context_is_api_allowed() for backends and make them use it.

Finally, have them return the final API as the return value (or 0 on
error).

And then use that api instead of a use_es boolean flag.

Fixes #4221
2021-10-08 03:31:07 +02:00
Benjamin Otte
dc6e831524 gdk: hdr => high depth
The term "hdr" is so overloaded, we shouldn't use them anywhere, except
from maybe describing all of this work in blog posts and other marketing
materials.

So do renames:
* hdr => high_depth
* request_hdr => prefers_high_depth

This more accurately describes what is going on.
2021-10-06 22:50:07 +02:00
Benjamin Otte
7ede468849 gdk: Add a request_hdr argument to begin_frame()
It's not used by anyone, it's just there.

gdk_draw_context_begin_frame_full() has been added so renderers can
make use of it.
2021-10-06 03:44:58 +02:00
Matthias Clasen
2a3a1aaf1e Merge branch 'fix-wgl-cairo-fallback' into 'master'
Apply MR !3964 to master (fix WGL->Cairo fallback-related items)

Closes #4257

See merge request GNOME/gtk!3987
2021-10-01 00:29:40 +00:00
Benjamin Otte
d4f9d38368 win32: Fix gcc warnings 2021-09-24 22:50:29 +02:00
Benjamin Otte
226ecaf9a2 win32: Don't include gdkinternals.h 2021-09-24 22:50:29 +02:00
Benjamin Otte
23acc993cc gdk: Make sure only one GL backend is used
Creative people managed to create an X11 display and a Wayland display
at once, thereby getting EGL and GLX involved in a fight to the death
over the ownership of the glFoo() symbolspace.

A way to force such a fight with available tools here is (on Wayland)
running something like:
GTK_INSPECTOR_DISPLAY=:1 GTK_DEBUG=interactive gtk4-demo

Related: xdg-desktop-portal-gnome#5
2021-09-24 01:59:37 +02:00