forked from 12to11/12to11
Check in new files for tearing control protocol
* tearing-control-v1.xml: * tearing_control.c: * tests/tearing_control_test.c: New files.
This commit is contained in:
parent
94333293c8
commit
4c7b4a2c5a
3 changed files with 581 additions and 0 deletions
120
tearing-control-v1.xml
Normal file
120
tearing-control-v1.xml
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="tearing_control_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2021 Xaver Hugl
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="wp_tearing_control_manager_v1" version="1">
|
||||||
|
<description summary="protocol for tearing control">
|
||||||
|
For some use cases like games or drawing tablets it can make sense to
|
||||||
|
reduce latency by accepting tearing with the use of asynchronous page
|
||||||
|
flips. This global is a factory interface, allowing clients to inform
|
||||||
|
which type of presentation the content of their surfaces is suitable for.
|
||||||
|
|
||||||
|
Graphics APIs like EGL or Vulkan, that manage the buffer queue and commits
|
||||||
|
of a wl_surface themselves, are likely to be using this extension
|
||||||
|
internally. If a client is using such an API for a wl_surface, it should
|
||||||
|
not directly use this extension on that surface, to avoid raising a
|
||||||
|
tearing_control_exists protocol error.
|
||||||
|
|
||||||
|
Warning! The protocol described in this file is currently in the testing
|
||||||
|
phase. Backward compatible changes may be added together with the
|
||||||
|
corresponding interface version bump. Backward incompatible changes can
|
||||||
|
only be done by creating a new major version of the extension.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy tearing control factory object">
|
||||||
|
Destroy this tearing control factory object. Other objects, including
|
||||||
|
wp_tearing_control_v1 objects created by this factory, are not affected
|
||||||
|
by this request.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="tearing_control_exists" value="0"
|
||||||
|
summary="the surface already has a tearing object associated"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="get_tearing_control">
|
||||||
|
<description summary="extend surface interface for tearing control">
|
||||||
|
Instantiate an interface extension for the given wl_surface to request
|
||||||
|
asynchronous page flips for presentation.
|
||||||
|
|
||||||
|
If the given wl_surface already has a wp_tearing_control_v1 object
|
||||||
|
associated, the tearing_control_exists protocol error is raised.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="wp_tearing_control_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="wp_tearing_control_v1" version="1">
|
||||||
|
<description summary="per-surface tearing control interface">
|
||||||
|
An additional interface to a wl_surface object, which allows the client
|
||||||
|
to hint to the compositor if the content on the surface is suitable for
|
||||||
|
presentation with tearing.
|
||||||
|
The default presentation hint is vsync. See presentation_hint for more
|
||||||
|
details.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="presentation_hint">
|
||||||
|
<description summary="presentation hint values">
|
||||||
|
This enum provides information for if submitted frames from the client
|
||||||
|
may be presented with tearing.
|
||||||
|
</description>
|
||||||
|
<entry name="vsync" value="0">
|
||||||
|
<description summary="tearing-free presentation">
|
||||||
|
The content of this surface is meant to be synchronized to the
|
||||||
|
vertical blanking period. This should not result in visible tearing
|
||||||
|
and may result in a delay before a surface commit is presented.
|
||||||
|
</description>
|
||||||
|
</entry>
|
||||||
|
<entry name="async" value="1">
|
||||||
|
<description summary="asynchronous presentation">
|
||||||
|
The content of this surface is meant to be presented with minimal
|
||||||
|
latency and tearing is acceptable.
|
||||||
|
</description>
|
||||||
|
</entry>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="set_presentation_hint">
|
||||||
|
<description summary="set presentation hint">
|
||||||
|
Set the presentation hint for the associated wl_surface. This state is
|
||||||
|
double-buffered and is applied on the next wl_surface.commit.
|
||||||
|
|
||||||
|
The compositor is free to dynamically respect or ignore this hint based
|
||||||
|
on various conditions like hardware capabilities, surface state and
|
||||||
|
user preferences.
|
||||||
|
</description>
|
||||||
|
<arg name="hint" type="uint" enum="presentation_hint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy tearing control object">
|
||||||
|
Destroy this surface tearing object and revert the presentation hint to
|
||||||
|
vsync. The change will be applied on the next wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
</protocol>
|
220
tearing_control.c
Normal file
220
tearing_control.c
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/* Wayland compositor running on top of an X server.
|
||||||
|
|
||||||
|
Copyright (C) 2022 to various contributors.
|
||||||
|
|
||||||
|
This file is part of 12to11.
|
||||||
|
|
||||||
|
12to11 is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
12to11 is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "compositor.h"
|
||||||
|
#include "tearing-control-v1.h"
|
||||||
|
|
||||||
|
typedef struct _TearingControl TearingControl;
|
||||||
|
|
||||||
|
struct _TearingControl
|
||||||
|
{
|
||||||
|
/* The associated surface. NULL when detached. */
|
||||||
|
Surface *surface;
|
||||||
|
|
||||||
|
/* The associated resource. */
|
||||||
|
struct wl_resource *resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The tearing control manager. */
|
||||||
|
static struct wl_global *tearing_control_manager_global;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DestroyTearingControl (struct wl_client *client, struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
TearingControl *control;
|
||||||
|
|
||||||
|
control = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (control->surface)
|
||||||
|
{
|
||||||
|
/* Reset the presentation hint. */
|
||||||
|
control->surface->pending_state.presentation_hint
|
||||||
|
= PresentationHintVsync;
|
||||||
|
control->surface->pending_state.pending
|
||||||
|
|= PendingPresentationHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SetPresentationHint (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t hint)
|
||||||
|
{
|
||||||
|
TearingControl *control;
|
||||||
|
|
||||||
|
control = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
if (control->surface)
|
||||||
|
{
|
||||||
|
switch (hint)
|
||||||
|
{
|
||||||
|
case WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC:
|
||||||
|
control->surface->pending_state.presentation_hint
|
||||||
|
= PresentationHintAsync;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
control->surface->pending_state.presentation_hint
|
||||||
|
= PresentationHintVsync;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
control->surface->pending_state.pending |= PendingPresentationHint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wp_tearing_control_v1_interface control_impl =
|
||||||
|
{
|
||||||
|
.destroy = DestroyTearingControl,
|
||||||
|
.set_presentation_hint = SetPresentationHint,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
HandleResourceDestroy (struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
TearingControl *control, **reference;
|
||||||
|
|
||||||
|
control = wl_resource_get_user_data (resource);
|
||||||
|
|
||||||
|
/* If the surface is still attached to the tearing control, remove
|
||||||
|
it from the surface. */
|
||||||
|
|
||||||
|
if (control->surface)
|
||||||
|
{
|
||||||
|
reference
|
||||||
|
= XLSurfaceFindClientData (control->surface,
|
||||||
|
TearingControlData);
|
||||||
|
XLAssert (reference != NULL);
|
||||||
|
|
||||||
|
*reference = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
XLFree (control);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
FreeTearingControlData (void *data)
|
||||||
|
{
|
||||||
|
TearingControl **control;
|
||||||
|
|
||||||
|
control = data;
|
||||||
|
|
||||||
|
if (!*control)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Detach the surface from the tearing control. */
|
||||||
|
(*control)->surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Destroy (struct wl_client *client, struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy (resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GetTearingControl (struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t id, struct wl_resource *surface_resource)
|
||||||
|
{
|
||||||
|
Surface *surface;
|
||||||
|
TearingControl **control;
|
||||||
|
|
||||||
|
surface = wl_resource_get_user_data (surface_resource);
|
||||||
|
control = XLSurfaceGetClientData (surface, TearingControlData,
|
||||||
|
sizeof *control,
|
||||||
|
FreeTearingControlData);
|
||||||
|
|
||||||
|
#define ControlExists \
|
||||||
|
WP_TEARING_CONTROL_MANAGER_V1_ERROR_TEARING_CONTROL_EXISTS
|
||||||
|
|
||||||
|
if (*control)
|
||||||
|
{
|
||||||
|
/* A tearing control resource already exists for this
|
||||||
|
surface. */
|
||||||
|
wl_resource_post_error (resource, ControlExists,
|
||||||
|
"a wp_tearing_control_v1 resource already exists"
|
||||||
|
" for the specified surface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ControlExists
|
||||||
|
|
||||||
|
(*control) = XLCalloc (1, sizeof **control);
|
||||||
|
(*control)->resource
|
||||||
|
= wl_resource_create (client,
|
||||||
|
&wp_tearing_control_v1_interface,
|
||||||
|
wl_resource_get_version (resource), id);
|
||||||
|
|
||||||
|
if (!(*control)->resource)
|
||||||
|
{
|
||||||
|
XLFree (*control);
|
||||||
|
(*control) = NULL;
|
||||||
|
|
||||||
|
wl_resource_post_no_memory (resource);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*control)->surface = surface;
|
||||||
|
wl_resource_set_implementation ((*control)->resource, &control_impl,
|
||||||
|
(*control), HandleResourceDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wp_tearing_control_manager_v1_interface manager_impl =
|
||||||
|
{
|
||||||
|
.destroy = Destroy,
|
||||||
|
.get_tearing_control = GetTearingControl,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
HandleBind (struct wl_client *client, void *data,
|
||||||
|
uint32_t version, uint32_t id)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
resource = wl_resource_create (client,
|
||||||
|
&wp_tearing_control_manager_v1_interface,
|
||||||
|
version, id);
|
||||||
|
|
||||||
|
if (!resource)
|
||||||
|
{
|
||||||
|
wl_client_post_no_memory (client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_set_implementation (resource, &manager_impl,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XLInitTearingControl (void)
|
||||||
|
{
|
||||||
|
tearing_control_manager_global
|
||||||
|
= wl_global_create (compositor.wl_display,
|
||||||
|
&wp_tearing_control_manager_v1_interface,
|
||||||
|
1, NULL, HandleBind);
|
||||||
|
}
|
241
tests/tearing_control_test.c
Normal file
241
tests/tearing_control_test.c
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
/* Tests for the Wayland compositor running on the X server.
|
||||||
|
|
||||||
|
Copyright (C) 2022 to various contributors.
|
||||||
|
|
||||||
|
This file is part of 12to11.
|
||||||
|
|
||||||
|
12to11 is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
12to11 is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include "test_harness.h"
|
||||||
|
#include "tearing-control-v1.h"
|
||||||
|
|
||||||
|
/* Tests for buffer release. */
|
||||||
|
|
||||||
|
enum test_kind
|
||||||
|
{
|
||||||
|
TEARING_CONTROL_KIND,
|
||||||
|
TEARING_DESTROY_KIND,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *test_names[] =
|
||||||
|
{
|
||||||
|
"tearing_control",
|
||||||
|
"tearing_destroy",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LAST_TEST TEARING_CONTROL_KIND
|
||||||
|
|
||||||
|
/* The display. */
|
||||||
|
static struct test_display *display;
|
||||||
|
|
||||||
|
/* The tearing control manager. */
|
||||||
|
static struct wp_tearing_control_manager_v1 *manager;
|
||||||
|
|
||||||
|
/* Test interfaces. */
|
||||||
|
static struct test_interface test_interfaces[] =
|
||||||
|
{
|
||||||
|
{ "wp_tearing_control_manager_v1", &manager,
|
||||||
|
&wp_tearing_control_manager_v1_interface, 1, },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The test surface and Wayland surface. */
|
||||||
|
static struct test_surface *test_surface;
|
||||||
|
static struct wl_surface *wayland_surface;
|
||||||
|
|
||||||
|
/* The tearing control. */
|
||||||
|
static struct wp_tearing_control_v1 *tearing_control;
|
||||||
|
|
||||||
|
/* The presentation hint used. 1 means async, and 0 means vsync. */
|
||||||
|
static int used_presentation_mode;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
static void verify_async_used (void);
|
||||||
|
static void verify_vsync_used (void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static struct test_buffer *
|
||||||
|
make_test_buffer (void)
|
||||||
|
{
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
struct test_buffer *test_buffer;
|
||||||
|
char *empty_data;
|
||||||
|
size_t stride;
|
||||||
|
|
||||||
|
stride = get_image_stride (display, 24, 1);
|
||||||
|
|
||||||
|
if (!stride)
|
||||||
|
report_test_failure ("unknown stride");
|
||||||
|
|
||||||
|
empty_data = calloc (1, stride);
|
||||||
|
|
||||||
|
if (!empty_data)
|
||||||
|
report_test_failure ("failed to allocate buffer data");
|
||||||
|
|
||||||
|
buffer = upload_image_data (display, empty_data, 1, 1, 24);
|
||||||
|
free (empty_data);
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
report_test_failure ("failed to create single pixel buffer");
|
||||||
|
|
||||||
|
test_buffer = get_test_buffer (display, buffer);
|
||||||
|
|
||||||
|
if (!test_buffer)
|
||||||
|
report_test_failure ("failed to create test buffer");
|
||||||
|
|
||||||
|
return test_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_single_step (enum test_kind kind)
|
||||||
|
{
|
||||||
|
struct test_buffer *buffer;
|
||||||
|
|
||||||
|
again:
|
||||||
|
|
||||||
|
test_log ("running test step: %s", test_names[kind]);
|
||||||
|
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case TEARING_CONTROL_KIND:
|
||||||
|
#define VSYNC WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
|
||||||
|
wp_tearing_control_v1_set_presentation_hint (tearing_control,
|
||||||
|
VSYNC);
|
||||||
|
#undef VSYNC
|
||||||
|
buffer = make_test_buffer ();
|
||||||
|
|
||||||
|
/* Attach the buffer. */
|
||||||
|
wl_surface_attach (wayland_surface, buffer->buffer, 0, 0);
|
||||||
|
wl_surface_commit (wayland_surface);
|
||||||
|
|
||||||
|
/* Now see what kind of presentation was used. */
|
||||||
|
verify_vsync_used ();
|
||||||
|
|
||||||
|
#define ASYNC WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC
|
||||||
|
wp_tearing_control_v1_set_presentation_hint (tearing_control,
|
||||||
|
ASYNC);
|
||||||
|
#undef ASYNC
|
||||||
|
wl_surface_commit (wayland_surface);
|
||||||
|
|
||||||
|
/* Now verify that async presentation was used. */
|
||||||
|
verify_async_used ();
|
||||||
|
|
||||||
|
kind = TEARING_DESTROY_KIND;
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
case TEARING_DESTROY_KIND:
|
||||||
|
/* Destroy the tearing control resource. */
|
||||||
|
wp_tearing_control_v1_destroy (tearing_control);
|
||||||
|
wl_surface_commit (wayland_surface);
|
||||||
|
|
||||||
|
/* Verify that the tearing hint reverted to vsync. */
|
||||||
|
verify_vsync_used ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kind == LAST_TEST)
|
||||||
|
test_complete ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_test_surface_mapped (void *data, struct test_surface *test_surface,
|
||||||
|
uint32_t xid, const char *display_string)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_test_surface_activated (void *data, struct test_surface *test_surface,
|
||||||
|
uint32_t months, uint32_t milliseconds,
|
||||||
|
struct wl_surface *activator_surface)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_test_surface_committed (void *data, struct test_surface *test_surface,
|
||||||
|
uint32_t presentation_hint)
|
||||||
|
{
|
||||||
|
used_presentation_mode = presentation_hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct test_surface_listener test_surface_listener =
|
||||||
|
{
|
||||||
|
handle_test_surface_mapped,
|
||||||
|
handle_test_surface_activated,
|
||||||
|
handle_test_surface_committed,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_async_used (void)
|
||||||
|
{
|
||||||
|
wl_display_roundtrip (display->display);
|
||||||
|
|
||||||
|
if (used_presentation_mode != 1)
|
||||||
|
report_test_failure ("async presentation not used where expected!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_vsync_used (void)
|
||||||
|
{
|
||||||
|
wl_display_roundtrip (display->display);
|
||||||
|
|
||||||
|
if (used_presentation_mode == 1)
|
||||||
|
report_test_failure ("vsync presentation not used where expected!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_test (void)
|
||||||
|
{
|
||||||
|
if (!make_test_surface (display, &wayland_surface,
|
||||||
|
&test_surface))
|
||||||
|
report_test_failure ("failed to create test surface");
|
||||||
|
|
||||||
|
test_surface_add_listener (test_surface, &test_surface_listener,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
tearing_control
|
||||||
|
= wp_tearing_control_manager_v1_get_tearing_control (manager,
|
||||||
|
wayland_surface);
|
||||||
|
|
||||||
|
if (!tearing_control)
|
||||||
|
report_test_failure ("failed to create tearing control");
|
||||||
|
|
||||||
|
test_single_step (TEARING_CONTROL_KIND);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (wl_display_dispatch (display->display) == -1)
|
||||||
|
die ("wl_display_dispatch");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
test_init ();
|
||||||
|
display = open_test_display (test_interfaces,
|
||||||
|
ARRAYELTS (test_interfaces));
|
||||||
|
|
||||||
|
if (!display)
|
||||||
|
report_test_failure ("failed to open display");
|
||||||
|
|
||||||
|
run_test ();
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue