Merge branch 'master.win32' into 'master'

Another round of fixes for GDK/Win32

See merge request GNOME/gtk!2369
This commit is contained in:
Matthias Clasen 2020-08-05 11:31:52 +00:00
commit c46f262d6e
9 changed files with 139 additions and 207 deletions

View File

@ -107,8 +107,6 @@ typedef struct {
guint realized : 1;
guint use_texture_rectangle : 1;
guint has_gl_framebuffer_blit : 1;
guint has_frame_terminator : 1;
guint has_khr_debug : 1;
guint use_khr_debug : 1;
guint has_unpack_subimage : 1;
@ -427,22 +425,6 @@ gdk_gl_context_use_texture_rectangle (GdkGLContext *context)
return priv->use_texture_rectangle;
}
gboolean
gdk_gl_context_has_framebuffer_blit (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
return priv->has_gl_framebuffer_blit;
}
gboolean
gdk_gl_context_has_frame_terminator (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
return priv->has_frame_terminator;
}
void
gdk_gl_context_push_debug_group (GdkGLContext *context,
const char *message)
@ -997,18 +979,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
has_npot = priv->gl_version >= 20;
has_texture_rectangle = FALSE;
/* This should check for GL_NV_framebuffer_blit as well - see extension at:
*
* https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt
*
* for ANGLE, we can enable bit blitting if we have the
* GL_ANGLE_framebuffer_blit extension
*/
priv->has_gl_framebuffer_blit = epoxy_has_gl_extension ("GL_ANGLE_framebuffer_blit");
/* No OES version */
priv->has_frame_terminator = FALSE;
priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
}
@ -1017,8 +987,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
has_npot = priv->gl_version >= 20 || epoxy_has_gl_extension ("GL_ARB_texture_non_power_of_two");
has_texture_rectangle = priv->gl_version >= 31 || epoxy_has_gl_extension ("GL_ARB_texture_rectangle");
priv->has_gl_framebuffer_blit = priv->gl_version >= 30 || epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
priv->has_unpack_subimage = TRUE;
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
@ -1052,8 +1020,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
"* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n"
" - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n"
" - GL_GREMEDY_frame_terminator: %s\n"
" - GL_KHR_debug: %s\n"
"* Using texture rectangle: %s",
priv->use_es ? "OpenGL ES" : "OpenGL",
@ -1062,8 +1028,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
glGetString (GL_SHADING_LANGUAGE_VERSION),
has_npot ? "yes" : "no",
has_texture_rectangle ? "yes" : "no",
priv->has_gl_framebuffer_blit ? "yes" : "no",
priv->has_frame_terminator ? "yes" : "no",
priv->has_khr_debug ? "yes" : "no",
priv->use_texture_rectangle ? "yes" : "no"));

View File

@ -87,8 +87,6 @@ void gdk_gl_context_upload_texture (GdkGLContext
guint texture_target);
GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context);
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
void gdk_gl_context_push_debug_group (GdkGLContext *context,
const char *message);

View File

@ -31,52 +31,6 @@
G_DEFINE_TYPE (GdkWin32CairoContext, gdk_win32_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
void
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
int scale,
RECT *return_window_rect)
{
RECT window_rect;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
_gdk_win32_get_window_client_area_rect (surface, scale, &window_rect);
/* Turn client area into window area */
_gdk_win32_adjust_client_rect (surface, &window_rect);
/* Convert GDK screen coordinates to W32 desktop coordinates */
window_rect.left -= _gdk_offset_x * impl->surface_scale;
window_rect.right -= _gdk_offset_x * impl->surface_scale;
window_rect.top -= _gdk_offset_y * impl->surface_scale;
window_rect.bottom -= _gdk_offset_y * impl->surface_scale;
*return_window_rect = window_rect;
}
void
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
RECT window_rect)
{
if (!IsIconic (GDK_SURFACE_HWND (surface)))
{
GDK_NOTE (EVENTS, g_print ("Setting window position ... "));
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
SWP_NOZORDER_SPECIFIED,
window_rect.left, window_rect.top,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW));
GDK_NOTE (EVENTS, g_print (" ... set window position\n"));
return;
}
/* Don't move iconic windows */
/* TODO: use SetWindowPlacement() to change non-minimized window position */
}
static cairo_surface_t *
create_cairo_surface_for_layered_window (GdkWin32Surface *impl,
int width,
@ -153,23 +107,7 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
impl = GDK_WIN32_SURFACE (surface);
scale = gdk_surface_get_scale_factor (surface);
self->layered = impl->layered;
gdk_win32_surface_get_queued_window_rect (surface, scale, &queued_window_rect);
/* Apply queued resizes for non-double-buffered and non-layered windows
* before painting them (we paint on the window DC directly,
* it must have the right size).
* Due to some poorly-undetstood issue delayed
* resizing of double-buffered windows can produce weird
* artefacts, so these are also resized before we paint.
*/
if (impl->drag_move_resize_context.native_move_resize_pending &&
!self->layered)
{
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
}
queued_window_rect = gdk_win32_surface_handle_queued_move_resize (draw_context);
width = queued_window_rect.right - queued_window_rect.left;
height = queued_window_rect.bottom - queued_window_rect.top;

View File

@ -104,25 +104,6 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
}
static void
gdk_gl_blit_region (GdkSurface *surface, cairo_region_t *region)
{
int n_rects, i;
int scale = gdk_surface_get_scale_factor (surface);
int wh = gdk_surface_get_height (surface);
cairo_rectangle_int_t rect;
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (region, i, &rect);
glScissor (rect.x * scale, (wh - rect.y - rect.height) * scale, rect.width * scale, rect.height * scale);
glBlitFramebuffer (rect.x * scale, (wh - rect.y - rect.height) * scale, (rect.x + rect.width) * scale, (wh - rect.y) * scale,
rect.x * scale, (wh - rect.y - rect.height) * scale, (rect.x + rect.width) * scale, (wh - rect.y) * scale,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
}
#ifdef GDK_WIN32_ENABLE_EGL
static gboolean
_get_is_egl_force_redraw (GdkSurface *surface)
@ -188,24 +169,7 @@ gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context,
}
}
if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN)
SwapBuffers (context_win32->gl_hdc);
else if (gdk_gl_context_has_framebuffer_blit (context))
{
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_BACK);
gdk_gl_blit_region (surface, painted);
glDrawBuffer(GL_BACK);
glFlush();
if (gdk_gl_context_has_frame_terminator (context))
glFrameTerminatorGREMEDY ();
}
else
{
g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
SwapBuffers (context_win32->gl_hdc);
}
SwapBuffers (context_win32->gl_hdc);
}
#ifdef GDK_WIN32_ENABLE_EGL
else
@ -224,15 +188,7 @@ gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context,
_reset_egl_force_redraw (surface);
}
if (cairo_region_contains_rectangle (painted, &whole_window) == CAIRO_REGION_OVERLAP_IN || force_egl_redraw_all)
eglSwapBuffers (display->egl_disp, egl_surface);
else if (gdk_gl_context_has_framebuffer_blit (context))
gdk_gl_blit_region (surface, painted);
else
{
g_warning ("Need to swap whole buffer even thouigh not everything was redrawn. Expect artifacts.");
eglSwapBuffers (display->egl_disp, egl_surface);
}
eglSwapBuffers (display->egl_disp, egl_surface);
}
#endif
}
@ -243,41 +199,12 @@ gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context,
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkSurface *surface;
GdkWin32Surface *impl;
RECT queued_window_rect;
surface = gdk_gl_context_get_surface (context);
impl = GDK_WIN32_SURFACE (surface);
gdk_win32_surface_get_queued_window_rect (surface,
gdk_surface_get_scale_factor (surface),
&queued_window_rect);
/* Apply queued resizes GL windows before painting them
* (we paint on the window DC directly, it must have the right size).
* Due to some poorly-understood issue delayed
* resizing of double-buffered windows can produce weird
* artefacts, so these are also resized before we paint.
*/
if (impl->drag_move_resize_context.native_move_resize_pending)
{
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
}
gdk_win32_surface_handle_queued_move_resize (draw_context);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_parent_class)->begin_frame (draw_context, update_area);
if (gdk_gl_context_get_shared_context (context))
return;
if (gdk_gl_context_has_framebuffer_blit (context))
return;
/* If nothing else is known, repaint everything so that the back
buffer is fully up-to-date for the swapbuffer */
cairo_region_union_rectangle (update_area, &(GdkRectangle) {
0, 0,
gdk_surface_get_width (surface),
gdk_surface_get_height (surface) });
}
typedef struct

View File

@ -45,6 +45,7 @@
#include "gdkwin32cursor.h"
#include "gdkglcontext-win32.h"
#include "gdkdisplay-win32.h"
#include "gdkcairocontext-win32.h"
#include <cairo-win32.h>
#include <dwmapi.h>
@ -216,7 +217,7 @@ _gdk_win32_get_window_client_area_rect (GdkSurface *window,
{
int x, y, width, height;
x = y = 0;
gdk_surface_get_geometry (window, &x, &y, NULL, NULL);
width = gdk_surface_get_width (window);
height = gdk_surface_get_height (window);
rect->left = x * scale;
@ -1979,7 +1980,7 @@ calculate_aerosnap_regions (GdkW32DragMoveResizeContext *context)
int i;
#endif
display = gdk_display_get_default ();
display = gdk_surface_get_display (context->window);
monitors = gdk_display_get_monitors (display);
#define _M_UP 0
@ -1999,7 +2000,6 @@ calculate_aerosnap_regions (GdkW32DragMoveResizeContext *context)
GdkMonitor *monitor;
monitor = g_list_model_get_item (monitors, monitor_idx);
g_object_unref (monitors);
gdk_win32_monitor_get_workarea (monitor, &wa);
gdk_monitor_get_geometry (monitor, &geometry);
@ -3428,8 +3428,8 @@ setup_drag_move_resize_context (GdkSurface *window,
GdkSurfaceEdge edge,
GdkDevice *device,
int button,
int x,
int y,
double x,
double y,
guint32 timestamp)
{
RECT rect;
@ -5102,3 +5102,87 @@ _gdk_win32_surface_get_egl_surface (GdkSurface *surface,
}
#endif
static void
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
int scale,
RECT *return_window_rect)
{
RECT window_rect;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
_gdk_win32_get_window_client_area_rect (surface, scale, &window_rect);
/* Turn client area into window area */
_gdk_win32_adjust_client_rect (surface, &window_rect);
/* Convert GDK screen coordinates to W32 desktop coordinates */
window_rect.left -= _gdk_offset_x * impl->surface_scale;
window_rect.right -= _gdk_offset_x * impl->surface_scale;
window_rect.top -= _gdk_offset_y * impl->surface_scale;
window_rect.bottom -= _gdk_offset_y * impl->surface_scale;
*return_window_rect = window_rect;
}
static void
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
RECT window_rect)
{
if (!IsIconic (GDK_SURFACE_HWND (surface)))
{
GDK_NOTE (EVENTS, g_print ("Setting window position ... "));
API_CALL (SetWindowPos, (GDK_SURFACE_HWND (surface),
SWP_NOZORDER_SPECIFIED,
window_rect.left, window_rect.top,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW));
GDK_NOTE (EVENTS, g_print (" ... set window position\n"));
return;
}
/* Don't move iconic windows */
/* TODO: use SetWindowPlacement() to change non-minimized window position */
}
RECT
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context)
{
GdkWin32CairoContext *cairo_ctx = NULL;
GdkSurface *surface;
GdkWin32Surface *impl;
int scale;
RECT queued_window_rect;
surface = gdk_draw_context_get_surface (draw_context);
impl = GDK_WIN32_SURFACE (surface);
scale = gdk_surface_get_scale_factor (surface);
if (GDK_IS_WIN32_CAIRO_CONTEXT (draw_context))
{
cairo_ctx = GDK_WIN32_CAIRO_CONTEXT (draw_context);
cairo_ctx->layered = impl->layered;
}
gdk_win32_surface_get_queued_window_rect (surface, scale, &queued_window_rect);
/* Apply queued resizes for non-double-buffered and non-layered windows
* before painting them (we paint on the window DC directly,
* it must have the right size).
* Due to some poorly-undetstood issue delayed
* resizing of double-buffered windows can produce weird
* artefacts, so these are also resized before we paint.
*/
if (impl->drag_move_resize_context.native_move_resize_pending &&
(cairo_ctx == NULL || !cairo_ctx->layered))
{
impl->drag_move_resize_context.native_move_resize_pending = FALSE;
gdk_win32_surface_apply_queued_move_resize (surface, queued_window_rect);
}
return queued_window_rect;
}

View File

@ -393,14 +393,8 @@ void gdk_win32_surface_move_resize (GdkSurface *window,
int width,
int height);
void
gdk_win32_surface_get_queued_window_rect (GdkSurface *surface,
int scale,
RECT *return_window_rect);
void
gdk_win32_surface_apply_queued_move_resize (GdkSurface *surface,
RECT window_rect);
RECT
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
#ifdef GDK_WIN32_ENABLE_EGL
EGLSurface _gdk_win32_surface_get_egl_surface (GdkSurface *surface,

View File

@ -72,12 +72,23 @@ gdk_win32_vulkan_context_create_surface (GdkVulkanContext *context,
return result;
}
static void
gdk_win32_vulkan_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_t *update_area)
{
gdk_win32_surface_handle_queued_move_resize (draw_context);
GDK_DRAW_CONTEXT_CLASS (gdk_win32_vulkan_context_parent_class)->begin_frame (draw_context, update_area);
}
static void
gdk_win32_vulkan_context_class_init (GdkWin32VulkanContextClass *klass)
{
GdkVulkanContextClass *context_class = GDK_VULKAN_CONTEXT_CLASS (klass);
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
context_class->create_surface = gdk_win32_vulkan_context_create_surface;
draw_context_class->begin_frame = gdk_win32_vulkan_context_begin_frame;
}
static void

View File

@ -92,7 +92,8 @@ renderers = [
foreach renderer : renderers
foreach test : compare_render_tests
if (renderer[1] == '' or not test.contains(renderer[1]))
if ((renderer[1] == '' or not test.contains(renderer[1])) and
(renderer[0] != 'broadway' or broadway_enabled))
test(renderer[0] + ' ' + test, compare_render,
args: ['--output', join_paths(meson.current_build_dir(), 'compare', renderer[0]),
join_paths(meson.current_source_dir(), 'compare', test + '.node'),

View File

@ -18,24 +18,39 @@ if get_option('debug')
common_env += [ 'GDK_DEBUG=default-settings' ]
endif
add_test_setup ('x11',
env: common_env + [
'GDK_BACKEND=x11',
'TEST_OUTPUT_SUBDIR=x11',
])
if x11_enabled
add_test_setup ('x11',
env: common_env + [
'GDK_BACKEND=x11',
'TEST_OUTPUT_SUBDIR=x11',
])
endif
add_test_setup ('wayland',
is_default: true,
env: common_env + [
'GDK_BACKEND=wayland',
'TEST_OUTPUT_SUBDIR=wayland',
])
if wayland_enabled
add_test_setup ('wayland',
is_default: true,
env: common_env + [
'GDK_BACKEND=wayland',
'TEST_OUTPUT_SUBDIR=wayland',
])
add_test_setup ('broadway',
env: common_env + [
'GDK_BACKEND=broadway',
'TEST_OUTPUT_SUBDIR=broadway',
])
endif
if os_win32
add_test_setup ('win32',
env: common_env + [
'GDK_BACKEND=win32',
'TEST_OUTPUT_SUBDIR=win32',
])
endif
if broadway_enabled
add_test_setup ('broadway',
env: common_env + [
'GDK_BACKEND=broadway',
'TEST_OUTPUT_SUBDIR=broadway',
])
endif
subdir('performance')
subdir('gdk')