Compare commits
78 Commits
xorg-serve
...
scaling-mr
Author | SHA1 | Date |
---|---|---|
Andrea Cavalli | ea5e7c688e | |
Andrea Cavalli | f5a4fe32db | |
Andrea Cavalli | 672bba9ed0 | |
Andrea Cavalli | d448ffcb05 | |
Andrea Cavalli | 012d982d90 | |
Andrea Cavalli | 6d2e5cd62e | |
Andrea Cavalli | e2d60a037c | |
Andrea Cavalli | 52687e0853 | |
Ryan Gonzalez | 18f1ce0b6e | |
Ryan Gonzalez | aa849658c5 | |
Christopher Snowhill | b46a9bba29 | |
Dario Nieuwenhuis | fbc7cefc43 | |
Povilas Kanapickas | 18d3131f9a | |
Povilas Kanapickas | 722da1c62c | |
Adam Jackson | 1f720dc9a3 | |
Adam Jackson | b49f0f9b32 | |
Adam Jackson | c1138d8ec8 | |
Adam Jackson | f3a98334e6 | |
Simon Ser | 6f63873da5 | |
Demi Marie Obenour | 659260a0b7 | |
Roman Gilg | e4dabe8d93 | |
Demi Marie Obenour | 31fb35a7af | |
Olivier Fourdan | 7eba412072 | |
Olivier Fourdan | f2781e9536 | |
Olivier Fourdan | f788289bdc | |
Olivier Fourdan | 6ea2c001f9 | |
Olivier Fourdan | a4ab57cb74 | |
Olivier Fourdan | 84897891e5 | |
Demi Marie Obenour | 5c2592cbb1 | |
Alex Richardson | d83c84bd9d | |
Zoltán Böszörményi | fb5322ce28 | |
Zoltán Böszörményi | f08bc32f5a | |
Zoltán Böszörményi | cd567415cc | |
Boris-Barboris | 16571b8926 | |
Łukasz Spintzyk | 8836b9d243 | |
Łukasz Spintzyk | d6c02ffd9c | |
Michel Dänzer | f6f2f203bc | |
Michel Dänzer | 212cfbcf68 | |
Michel Dänzer | fe8c7855f3 | |
Michel Dänzer | 31d2ebca77 | |
Michel Dänzer | 495ec59664 | |
Michel Dänzer | f73340445f | |
Michel Dänzer | aac31d2758 | |
Michel Dänzer | f8c086b214 | |
Michel Dänzer | c30f3d08ac | |
Michel Dänzer | 4503c8d9ea | |
Michel Dänzer | b2a06e0700 | |
Michel Dänzer | fc53e3c536 | |
Michel Dänzer | c592c66625 | |
Michel Dänzer | 4230176080 | |
Michel Dänzer | 61cc5d96ed | |
Michel Dänzer | 35f173ddb6 | |
Michel Dänzer | 0517460301 | |
Michel Dänzer | 490248ea70 | |
Michel Dänzer | 0c0cbbc7cb | |
Michel Dänzer | 561c63d0f1 | |
Michel Dänzer | a67f16fde1 | |
Michel Dänzer | 080c1ca3f5 | |
Michel Dänzer | c22887bc7a | |
Michel Dänzer | cb35ff596e | |
Michel Dänzer | 7b78cf6b3a | |
Michel Dänzer | 244403ec87 | |
Michel Dänzer | f7adbc2166 | |
Michel Dänzer | 7fd114365d | |
Michel Dänzer | 2e1dcd731f | |
Michel Dänzer | b6419359b6 | |
Michel Dänzer | c35a716b02 | |
Michel Dänzer | 10bdd87fe4 | |
Michel Dänzer | b6d54b0f5d | |
Michel Dänzer | 93666ebe37 | |
Michel Dänzer | 44f705a5b6 | |
Michel Dänzer | 86e645bcfa | |
Michel Dänzer | ba8763c27b | |
Michel Dänzer | 204f10c29e | |
Michel Dänzer | a6d178b6af | |
Matt Turner | 7e20c8b7b8 | |
Dave Airlie | a955286869 | |
Dave Airlie | a2f5b917f5 |
|
@ -11,7 +11,7 @@ variables:
|
|||
FDO_UPSTREAM_REPO: xorg/xserver
|
||||
FDO_DISTRIBUTION_VERSION: buster-slim
|
||||
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/debian-install.sh'
|
||||
FDO_DISTRIBUTION_TAG: "2021-05-17"
|
||||
FDO_DISTRIBUTION_TAG: "2021-07-09"
|
||||
|
||||
include:
|
||||
- project: 'freedesktop/ci-templates'
|
||||
|
|
|
@ -107,6 +107,14 @@ apt-get install -y \
|
|||
|
||||
cd /root
|
||||
|
||||
# xserver requires libxcvt
|
||||
git clone https://gitlab.freedesktop.org/xorg/lib//libxcvt.git --depth 1 --branch=libxcvt-0.1.0
|
||||
cd libxcvt
|
||||
meson _build
|
||||
ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
|
||||
cd ..
|
||||
rm -rf libxcvt
|
||||
|
||||
# xserver requires xorgproto >= 2021.4.99.2 for XI 2.3.99.1
|
||||
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2021.4.99.2
|
||||
pushd xorgproto
|
||||
|
|
|
@ -138,9 +138,15 @@ ProcGEDispatch(ClientPtr client)
|
|||
static int _X_COLD
|
||||
SProcGEDispatch(ClientPtr client)
|
||||
{
|
||||
GEClientInfoPtr pGEClient = GEGetClient(client);
|
||||
|
||||
REQUEST(xGEReq);
|
||||
if (stuff->ReqType >= GENumberRequests)
|
||||
|
||||
if (pGEClient->major_version >= ARRAY_SIZE(version_requests))
|
||||
return BadRequest;
|
||||
if (stuff->ReqType > version_requests[pGEClient->major_version])
|
||||
return BadRequest;
|
||||
|
||||
return (*SProcGEVector[stuff->ReqType]) (client);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid)
|
||||
|
||||
typedef struct {
|
||||
security_context_t octx;
|
||||
security_context_t dctx;
|
||||
char *octx;
|
||||
char *dctx;
|
||||
CARD32 octx_len;
|
||||
CARD32 dctx_len;
|
||||
CARD32 id;
|
||||
|
@ -48,10 +48,10 @@ typedef struct {
|
|||
* Extension Dispatch
|
||||
*/
|
||||
|
||||
static security_context_t
|
||||
static char *
|
||||
SELinuxCopyContext(char *ptr, unsigned len)
|
||||
{
|
||||
security_context_t copy = malloc(len + 1);
|
||||
char *copy = malloc(len + 1);
|
||||
|
||||
if (!copy)
|
||||
return NULL;
|
||||
|
@ -84,7 +84,7 @@ static int
|
|||
SELinuxSendContextReply(ClientPtr client, security_id_t sid)
|
||||
{
|
||||
SELinuxGetContextReply rep;
|
||||
security_context_t ctx = NULL;
|
||||
char *ctx = NULL;
|
||||
int len = 0;
|
||||
|
||||
if (sid) {
|
||||
|
@ -117,7 +117,7 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
|
|||
{
|
||||
PrivateRec **privPtr = &client->devPrivates;
|
||||
security_id_t *pSid;
|
||||
security_context_t ctx = NULL;
|
||||
char *ctx = NULL;
|
||||
char *ptr;
|
||||
int rc;
|
||||
|
||||
|
@ -165,7 +165,7 @@ ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset)
|
|||
static int
|
||||
ProcSELinuxSetDeviceContext(ClientPtr client)
|
||||
{
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
security_id_t sid;
|
||||
DeviceIntPtr dev;
|
||||
SELinuxSubjectRec *subj;
|
||||
|
|
|
@ -114,7 +114,7 @@ SELinuxLabelClient(ClientPtr client)
|
|||
int fd = XaceGetConnectionNumber(client);
|
||||
SELinuxSubjectRec *subj;
|
||||
SELinuxObjectRec *obj;
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
|
||||
subj = dixLookupPrivate(&client->devPrivates, subjectKey);
|
||||
obj = dixLookupPrivate(&client->devPrivates, objectKey);
|
||||
|
@ -169,7 +169,7 @@ SELinuxLabelInitial(void)
|
|||
XaceScreenAccessRec srec;
|
||||
SELinuxSubjectRec *subj;
|
||||
SELinuxObjectRec *obj;
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
void *unused;
|
||||
|
||||
/* Do the serverClient */
|
||||
|
@ -773,7 +773,7 @@ SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
|
|||
subj = dixLookupPrivate(&wClient(pWin)->devPrivates, subjectKey);
|
||||
|
||||
if (subj->sid) {
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
int rc = avc_sid_to_context_raw(subj->sid, &ctx);
|
||||
|
||||
if (rc < 0)
|
||||
|
@ -791,7 +791,7 @@ SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
|
|||
obj = dixLookupPrivate(&pWin->devPrivates, objectKey);
|
||||
|
||||
if (obj->sid) {
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
int rc = avc_sid_to_context_raw(obj->sid, &ctx);
|
||||
|
||||
if (rc < 0)
|
||||
|
@ -847,7 +847,7 @@ void
|
|||
SELinuxFlaskInit(void)
|
||||
{
|
||||
struct selinux_opt avc_option = { AVC_OPT_SETENFORCE, (char *) 0 };
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
int ret = TRUE;
|
||||
|
||||
switch (selinuxEnforcingState) {
|
||||
|
|
|
@ -97,7 +97,7 @@ static int
|
|||
SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec * obj, int map, int polymap)
|
||||
{
|
||||
const char *name = NameForAtom(atom);
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
int rc = Success;
|
||||
|
||||
obj->poly = 1;
|
||||
|
@ -255,7 +255,7 @@ SELinuxEventToSID(unsigned type, security_id_t sid_of_window,
|
|||
{
|
||||
const char *name = LookupEventName(type);
|
||||
security_id_t sid;
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
|
||||
type &= 127;
|
||||
|
||||
|
@ -291,7 +291,7 @@ SELinuxEventToSID(unsigned type, security_id_t sid_of_window,
|
|||
int
|
||||
SELinuxExtensionToSID(const char *name, security_id_t * sid_rtn)
|
||||
{
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
|
||||
/* Look in the mappings of extension names to contexts */
|
||||
if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EXT) < 0) {
|
||||
|
@ -347,10 +347,10 @@ SELinuxTypeToClass(RESTYPE type)
|
|||
return (security_class_t) (unsigned long) tmp;
|
||||
}
|
||||
|
||||
security_context_t
|
||||
char *
|
||||
SELinuxDefaultClientLabel(void)
|
||||
{
|
||||
security_context_t ctx;
|
||||
char *ctx;
|
||||
|
||||
if (selabel_lookup_raw(label_hnd, &ctx, "remote", SELABEL_X_CLIENT) < 0)
|
||||
FatalError("SELinux: failed to look up remote-client context\n");
|
||||
|
|
|
@ -99,7 +99,7 @@ int
|
|||
|
||||
security_class_t SELinuxTypeToClass(RESTYPE type);
|
||||
|
||||
security_context_t SELinuxDefaultClientLabel(void);
|
||||
char *SELinuxDefaultClientLabel(void);
|
||||
|
||||
void
|
||||
SELinuxLabelInit(void);
|
||||
|
|
|
@ -39,6 +39,6 @@
|
|||
int SProcXIChangeHierarchy(ClientPtr /* client */ );
|
||||
int ProcXIChangeHierarchy(ClientPtr /* client */ );
|
||||
|
||||
void XISendDeviceHierarchyEvent(int flags[]);
|
||||
void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]);
|
||||
|
||||
#endif /* CHDEVHIER_H */
|
||||
|
|
15
configure.ac
15
configure.ac
|
@ -31,7 +31,7 @@ RELEASE_DATE="2021-07-05"
|
|||
RELEASE_NAME="Carrot and Ginger Soup"
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([foreign dist-bzip2])
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
# Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS
|
||||
|
@ -758,6 +758,7 @@ LIBUDEV="libudev >= 143"
|
|||
LIBSELINUX="libselinux >= 2.0.86"
|
||||
LIBDBUS="dbus-1 >= 1.0"
|
||||
LIBPIXMAN="pixman-1 >= 0.27.2"
|
||||
LIBXCVT="libxcvt"
|
||||
|
||||
dnl Pixman is always required, but we separate it out so we can link
|
||||
dnl specific modules against it
|
||||
|
@ -765,7 +766,7 @@ PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
|
|||
REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau"
|
||||
|
||||
dnl Core modules for most extensions, et al.
|
||||
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN"
|
||||
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN $LIBXCVT"
|
||||
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
|
||||
AC_SUBST(SDK_REQUIRED_MODULES)
|
||||
|
||||
|
@ -1758,11 +1759,14 @@ fi
|
|||
AC_MSG_RESULT([$XORG])
|
||||
|
||||
if test "x$XORG" = xyes; then
|
||||
PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT)
|
||||
|
||||
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
|
||||
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
|
||||
XORG_INCS="$XORG_DDXINCS $XORG_OSINCS"
|
||||
XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H"
|
||||
XORG_CFLAGS="$XORGSERVER_CFLAGS $LIBXCVT_CFLAGS -DHAVE_XORG_CONFIG_H"
|
||||
XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB"
|
||||
XORG_SYS_LIBS="$XORG_SYS_LIBS $LIBXCVT_LIBS"
|
||||
|
||||
dnl ==================================================================
|
||||
dnl symbol visibility
|
||||
|
@ -2347,8 +2351,10 @@ if test "x$XWAYLAND" = xyes; then
|
|||
AC_SUBST(have_eglstream, "false")
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT)
|
||||
|
||||
XWAYLAND_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
|
||||
XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS"
|
||||
XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS $LIBXCVT_LIBS"
|
||||
AC_SUBST([XWAYLAND_LIBS])
|
||||
AC_SUBST([XWAYLAND_SYS_LIBS])
|
||||
|
||||
|
@ -2482,7 +2488,6 @@ hw/xfree86/x86emu/Makefile
|
|||
hw/xfree86/xkb/Makefile
|
||||
hw/xfree86/utils/Makefile
|
||||
hw/xfree86/utils/man/Makefile
|
||||
hw/xfree86/utils/cvt/Makefile
|
||||
hw/xfree86/utils/gtf/Makefile
|
||||
hw/dmx/config/Makefile
|
||||
hw/dmx/config/man/Makefile
|
||||
|
|
|
@ -561,7 +561,11 @@ static int _X_COLD
|
|||
SProcDamageDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xDamageReq);
|
||||
if (stuff->damageReqType >= XDamageNumberRequests)
|
||||
DamageClientPtr pDamageClient = GetDamageClient(client);
|
||||
|
||||
if (pDamageClient->major_version >= ARRAY_SIZE(version_requests))
|
||||
return BadRequest;
|
||||
if (stuff->damageReqType > version_requests[pDamageClient->major_version])
|
||||
return BadRequest;
|
||||
return (*SProcDamageVector[stuff->damageReqType]) (client);
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ ProcChangeProperty(ClientPtr client)
|
|||
int
|
||||
dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
|
||||
Atom type, int format, int mode, unsigned long len,
|
||||
void *value, Bool sendevent)
|
||||
const void *value, Bool sendevent)
|
||||
{
|
||||
PropertyPtr pProp;
|
||||
PropertyRec savedProp;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
if build_docs
|
||||
basename = 'Xserver-DTrace'
|
||||
|
||||
input_xml = basename + '.xml'
|
||||
|
||||
custom_target(
|
||||
basename + '.html',
|
||||
output: basename + '.html',
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
|
||||
'--stringparam', 'target.database.document=' + join_paths(doc_sgml_path, 'X11/dbs/masterdb.html.xml'),
|
||||
'--stringparam', 'current.docid=' + basename,
|
||||
'-o', meson.current_build_dir(),
|
||||
'xhtml-nochunks', '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('datadir'), 'doc/xorg-server'),
|
||||
)
|
||||
|
||||
if build_docs_pdf
|
||||
foreach format : ['ps', 'pdf']
|
||||
output_fn = basename + '.' + format
|
||||
custom_target(
|
||||
output_fn,
|
||||
output: output_fn,
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
|
||||
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
|
||||
'--stringparam', 'target.database.document=' + join_paths(doc_sgml_path, 'X11/dbs/masterdb.pdf.xml'),
|
||||
'--stringparam', 'current.docid=' + basename,
|
||||
'-o', meson.current_build_dir(),
|
||||
'--with-fop', format, '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('datadir'), 'doc/xorg-server'),
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
|
||||
foreach format_data : [['html', 'xorg-xhtml.xsl'], ['pdf', 'xorg-fo.xsl']]
|
||||
format = format_data[0]
|
||||
stylesheet = format_data[1]
|
||||
output_fn = basename + '.' + format + '.db'
|
||||
custom_target(
|
||||
output_fn,
|
||||
output: output_fn,
|
||||
input: [input_xml],
|
||||
command: [xsltproc] + docs_xslt_search_flags + [
|
||||
'--stringparam', 'targets.filename', output_fn,
|
||||
'--stringparam', 'collect.xref.targets', 'only',
|
||||
'--stringparam', 'olink.base.uri', basename + '.' + format,
|
||||
'--nonet',
|
||||
'--output', join_paths(meson.current_build_dir(), output_fn),
|
||||
'--xinclude', join_paths(doc_stylesheet_srcdir, stylesheet),
|
||||
'@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: true,
|
||||
install_dir: join_paths(get_option('datadir'), 'doc/xorg-server'),
|
||||
)
|
||||
endforeach
|
||||
endif
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
if build_docs_devel
|
||||
foreach basename : ['Xserver-spec', 'Xinput']
|
||||
|
||||
input_xml = basename + '.xml'
|
||||
|
||||
custom_target(
|
||||
basename + '.html',
|
||||
output: basename + '.html',
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
|
||||
'-o', meson.current_build_dir(),
|
||||
'xhtml-nochunks', '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: false,
|
||||
)
|
||||
|
||||
if build_docs_pdf
|
||||
foreach format : ['ps', 'pdf']
|
||||
output_fn = basename + '.' + format
|
||||
custom_target(
|
||||
output_fn,
|
||||
output: output_fn,
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
|
||||
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
|
||||
'-o', meson.current_build_dir(),
|
||||
'--with-fop', format, '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: false,
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
endforeach
|
||||
endif
|
||||
|
||||
subdir('dtrace')
|
|
@ -746,7 +746,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
* have instanced arrays, but this is not always the case.
|
||||
* etnaviv offers GLSL 140 with OpenGL 2.1.
|
||||
*/
|
||||
if (glamor_priv->glsl_version >= 130 &&
|
||||
if (glamor_glsl_has_ints(glamor_priv) &&
|
||||
!epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
|
||||
glamor_priv->glsl_version = 120;
|
||||
} else {
|
||||
|
@ -772,6 +772,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (!glamor_priv->is_gles && glamor_priv->glsl_version == 120 &&
|
||||
epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
|
||||
glamor_priv->use_gpu_shader4 = epoxy_has_gl_extension("GL_EXT_gpu_shader4");
|
||||
|
||||
glamor_priv->has_rw_pbo = FALSE;
|
||||
if (!glamor_priv->is_gles)
|
||||
glamor_priv->has_rw_pbo = TRUE;
|
||||
|
@ -799,7 +803,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
|||
epoxy_gl_version() >= 30 ||
|
||||
epoxy_has_gl_extension("GL_NV_pack_subimage");
|
||||
glamor_priv->has_dual_blend =
|
||||
glamor_priv->glsl_version >= 130 &&
|
||||
glamor_glsl_has_ints(glamor_priv) &&
|
||||
epoxy_has_gl_extension("GL_ARB_blend_func_extended");
|
||||
glamor_priv->has_clear_texture =
|
||||
epoxy_gl_version() >= 44 ||
|
||||
|
|
|
@ -208,11 +208,6 @@ static const glamor_facet glamor_facet_composite_glyphs_120 = {
|
|||
.locations = glamor_program_location_atlas,
|
||||
};
|
||||
|
||||
static inline Bool
|
||||
glamor_glyph_use_130(glamor_screen_private *glamor_priv) {
|
||||
return glamor_priv->glsl_version >= 130;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_glyphs_init_facet(ScreenPtr screen)
|
||||
{
|
||||
|
@ -274,7 +269,7 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
|
|||
box->y2 - box->y1);
|
||||
box++;
|
||||
|
||||
if (glamor_glyph_use_130(glamor_priv))
|
||||
if (glamor_glsl_has_ints(glamor_priv))
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
|
||||
else
|
||||
glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph);
|
||||
|
@ -287,7 +282,7 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
|
|||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
if (glamor_glyph_use_130(glamor_priv)) {
|
||||
if (glamor_glsl_has_ints(glamor_priv)) {
|
||||
glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
|
||||
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
|
||||
}
|
||||
|
@ -305,7 +300,7 @@ glamor_glyph_start(ScreenPtr screen, int count)
|
|||
|
||||
/* Set up the vertex buffers for the font and destination */
|
||||
|
||||
if (glamor_glyph_use_130(glamor_priv)) {
|
||||
if (glamor_glsl_has_ints(glamor_priv)) {
|
||||
v = glamor_get_vbo_space(screen, count * (6 * sizeof (GLshort)), &vbo_offset);
|
||||
|
||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
@ -439,7 +434,7 @@ glamor_composite_glyphs(CARD8 op,
|
|||
/* First glyph in the current atlas?
|
||||
*/
|
||||
if (_X_UNLIKELY(glyphs_queued == 0)) {
|
||||
if (glamor_glyph_use_130(glamor_priv))
|
||||
if (glamor_glsl_has_ints(glamor_priv))
|
||||
prog = glamor_setup_program_render(op, src, glyph_pict, dst,
|
||||
glyphs_program,
|
||||
&glamor_facet_composite_glyphs_130,
|
||||
|
@ -458,7 +453,7 @@ glamor_composite_glyphs(CARD8 op,
|
|||
*/
|
||||
|
||||
glyphs_queued++;
|
||||
if (_X_LIKELY(glamor_glyph_use_130(glamor_priv))) {
|
||||
if (_X_LIKELY(glamor_glsl_has_ints(glamor_priv))) {
|
||||
v[0] = x - glyph->info.x;
|
||||
v[1] = y - glyph->info.y;
|
||||
v[2] = glyph_draw->width;
|
||||
|
|
|
@ -1060,9 +1060,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
|
|||
goto error;
|
||||
}
|
||||
if (strstr((const char *)renderer, "llvmpipe")) {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
||||
"Refusing to try glamor on llvmpipe\n");
|
||||
goto error;
|
||||
if (scrn->confScreen->num_gpu_devices)
|
||||
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
||||
"Allowing glamor on llvmpipe for PRIME\n");
|
||||
else {
|
||||
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
||||
"Refusing to try glamor on llvmpipe\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,7 +47,7 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
|
|||
unsigned long count;
|
||||
char *bits;
|
||||
|
||||
if (glamor_priv->glsl_version < 130)
|
||||
if (!glamor_glsl_has_ints(glamor_priv))
|
||||
return NULL;
|
||||
|
||||
privates = FontGetPrivate(font, glamor_font_private_index);
|
||||
|
@ -210,7 +210,7 @@ glamor_font_init(ScreenPtr screen)
|
|||
{
|
||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
|
||||
if (glamor_priv->glsl_version < 130)
|
||||
if (!glamor_glsl_has_ints(glamor_priv))
|
||||
return TRUE;
|
||||
|
||||
if (glamor_font_generation != serverGeneration) {
|
||||
|
|
|
@ -213,6 +213,7 @@ typedef struct glamor_screen_private {
|
|||
Bool has_texture_swizzle;
|
||||
Bool is_core_profile;
|
||||
Bool can_copyplane;
|
||||
Bool use_gpu_shader4;
|
||||
int max_fbo_size;
|
||||
|
||||
struct glamor_format formats[33];
|
||||
|
|
|
@ -187,6 +187,7 @@ fs_location_vars(glamor_program_location locations)
|
|||
|
||||
static const char vs_template[] =
|
||||
"%s" /* version */
|
||||
"%s" /* exts */
|
||||
"%s" /* defines */
|
||||
"%s" /* prim vs_vars */
|
||||
"%s" /* fill vs_vars */
|
||||
|
@ -199,6 +200,7 @@ static const char vs_template[] =
|
|||
|
||||
static const char fs_template[] =
|
||||
"%s" /* version */
|
||||
"%s" /* exts */
|
||||
GLAMOR_DEFAULT_PRECISION
|
||||
"%s" /* defines */
|
||||
"%s" /* prim fs_vars */
|
||||
|
@ -262,6 +264,7 @@ glamor_build_program(ScreenPtr screen,
|
|||
char *fs_prog_string;
|
||||
|
||||
GLint fs_prog, vs_prog;
|
||||
Bool gpu_shader4 = FALSE;
|
||||
|
||||
if (!fill)
|
||||
fill = &facet_null_fill;
|
||||
|
@ -270,8 +273,14 @@ glamor_build_program(ScreenPtr screen,
|
|||
flags |= fill->flags;
|
||||
version = MAX(version, fill->version);
|
||||
|
||||
if (version > glamor_priv->glsl_version)
|
||||
goto fail;
|
||||
if (version > glamor_priv->glsl_version) {
|
||||
if (version == 130 && !glamor_priv->use_gpu_shader4)
|
||||
goto fail;
|
||||
else {
|
||||
version = 120;
|
||||
gpu_shader4 = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
vs_vars = vs_location_vars(locations);
|
||||
fs_vars = fs_location_vars(locations);
|
||||
|
@ -291,6 +300,7 @@ glamor_build_program(ScreenPtr screen,
|
|||
if (asprintf(&vs_prog_string,
|
||||
vs_template,
|
||||
str(version_string),
|
||||
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n" : "",
|
||||
str(defines),
|
||||
str(prim->vs_vars),
|
||||
str(fill->vs_vars),
|
||||
|
@ -302,6 +312,7 @@ glamor_build_program(ScreenPtr screen,
|
|||
if (asprintf(&fs_prog_string,
|
||||
fs_template,
|
||||
str(version_string),
|
||||
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n#define texelFetch texelFetch2D\n#define uint unsigned int\n" : "",
|
||||
str(defines),
|
||||
str(prim->fs_vars),
|
||||
str(fill->fs_vars),
|
||||
|
|
|
@ -69,7 +69,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
|
|||
glamor_bounds_union_rect(&bounds, &prect[i]);
|
||||
}
|
||||
|
||||
if (glamor_priv->glsl_version >= 130) {
|
||||
if (glamor_glsl_has_ints(glamor_priv)) {
|
||||
prog = glamor_use_program_fill(pixmap, gc,
|
||||
&glamor_priv->poly_fill_rect_program,
|
||||
&glamor_facet_polyfillrect_130);
|
||||
|
@ -151,7 +151,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
|
|||
scissor.y1 + off_y,
|
||||
scissor.x2 - scissor.x1,
|
||||
scissor.y2 - scissor.y1);
|
||||
if (glamor_priv->glsl_version >= 130)
|
||||
if (glamor_glsl_has_ints(glamor_priv))
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
|
||||
else {
|
||||
glamor_glDrawArrays_GL_QUADS(glamor_priv, nrect);
|
||||
|
@ -163,7 +163,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
|
|||
|
||||
bail:
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
if (glamor_priv->glsl_version >= 130) {
|
||||
if (glamor_glsl_has_ints(glamor_priv)) {
|
||||
glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
|
||||
|
|
|
@ -560,8 +560,8 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
|
|||
case PictFilterGood:
|
||||
case PictFilterBest:
|
||||
case PictFilterBilinear:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
|
|||
|
||||
glamor_make_current(glamor_priv);
|
||||
|
||||
if (glamor_priv->glsl_version >= 130) {
|
||||
if (glamor_glsl_has_ints(glamor_priv)) {
|
||||
prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
|
||||
&glamor_facet_fillspans_130);
|
||||
|
||||
|
@ -134,7 +134,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
|
|||
box->x2 - box->x1,
|
||||
box->y2 - box->y1);
|
||||
box++;
|
||||
if (glamor_priv->glsl_version >= 130)
|
||||
if (glamor_glsl_has_ints(glamor_priv))
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
|
||||
else {
|
||||
glamor_glDrawArrays_GL_QUADS(glamor_priv, n);
|
||||
|
@ -146,7 +146,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
|
|||
|
||||
bail:
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
if (glamor_priv->glsl_version >= 130)
|
||||
if (glamor_glsl_has_ints(glamor_priv))
|
||||
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
|
||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||
|
||||
|
|
|
@ -732,5 +732,9 @@ glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
|
|||
}
|
||||
}
|
||||
|
||||
static inline Bool
|
||||
glamor_glsl_has_ints(glamor_screen_private *glamor_priv) {
|
||||
return glamor_priv->glsl_version >= 130 || glamor_priv->use_gpu_shader4;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -380,15 +380,15 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
|
|||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
@ -397,8 +397,8 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
|
|||
case FOURCC_I420:
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
break;
|
||||
|
|
|
@ -72,7 +72,6 @@ typedef struct DMXConfigCmdStruct {
|
|||
DMXConfigList *xinputs;
|
||||
} DMXConfigCmd, *DMXConfigCmdPtr;
|
||||
|
||||
extern DMXConfigEntryPtr dmxConfigEntry;
|
||||
static DMXConfigCmd dmxConfigCmd;
|
||||
|
||||
static int dmxDisplaysFromCommandLine;
|
||||
|
|
|
@ -65,7 +65,6 @@ extern FILE *yyin;
|
|||
#define DMX_CANVAS_WIDTH 400
|
||||
#define DMX_CANVAS_HEIGHT 500
|
||||
|
||||
extern DMXConfigEntryPtr dmxConfigEntry;
|
||||
static DMXConfigVirtualPtr dmxConfigCurrent, dmxConfigNewVirtual;
|
||||
static DMXConfigDisplayPtr dmxConfigCurrentDisplay, dmxConfigNewDisplay;
|
||||
static int dmxConfigGrabbed, dmxConfigGrabbedFine;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
if build_docs_devel
|
||||
foreach basename : ['dmx', 'scaled']
|
||||
|
||||
input_xml = basename + '.xml'
|
||||
|
||||
custom_target(
|
||||
basename + '.html',
|
||||
output: basename + '.html',
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
|
||||
'-o', meson.current_build_dir(),
|
||||
'xhtml-nochunks', '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: false,
|
||||
)
|
||||
|
||||
if build_docs_pdf
|
||||
foreach format : ['ps', 'pdf']
|
||||
output_fn = basename + '.' + format
|
||||
custom_target(
|
||||
output_fn,
|
||||
output: output_fn,
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
|
||||
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
|
||||
'-o', meson.current_build_dir(),
|
||||
'--with-fop', format, '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: false,
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
endforeach
|
||||
endif
|
|
@ -27,7 +27,7 @@ srcs = [
|
|||
subdir('config')
|
||||
subdir('input')
|
||||
subdir('examples')
|
||||
# XXX: subdir('doc')
|
||||
subdir('doc')
|
||||
# XXX: subdir('doxygen')
|
||||
|
||||
install_man(configure_file(
|
||||
|
|
|
@ -106,6 +106,37 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
|
|||
return foundScreen;
|
||||
}
|
||||
|
||||
static screenLayoutPtr
|
||||
xf86BusConfigMatch(ScrnInfoPtr scrnInfo, Bool is_gpu) {
|
||||
screenLayoutPtr layout;
|
||||
int i, j;
|
||||
|
||||
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
|
||||
layout++) {
|
||||
for (i = 0; i < scrnInfo->numEntities; i++) {
|
||||
GDevPtr dev =
|
||||
xf86GetDevFromEntity(scrnInfo->entityList[i],
|
||||
scrnInfo->entityInstanceList[i]);
|
||||
|
||||
if (is_gpu) {
|
||||
for (j = 0; j < layout->screen->num_gpu_devices; j++) {
|
||||
if (dev == layout->screen->gpu_devices[j]) {
|
||||
/* A match has been found */
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dev == layout->screen->device) {
|
||||
/* A match has been found */
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TRUE if all buses are configured and set up correctly and FALSE
|
||||
* otherwise.
|
||||
|
@ -114,7 +145,7 @@ Bool
|
|||
xf86BusConfig(void)
|
||||
{
|
||||
screenLayoutPtr layout;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* 3 step probe to (hopefully) ensure that we always find at least 1
|
||||
|
@ -170,27 +201,10 @@ xf86BusConfig(void)
|
|||
*
|
||||
*/
|
||||
for (i = 0; i < xf86NumScreens; i++) {
|
||||
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
|
||||
layout++) {
|
||||
Bool found = FALSE;
|
||||
|
||||
for (j = 0; j < xf86Screens[i]->numEntities; j++) {
|
||||
|
||||
GDevPtr dev =
|
||||
xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
|
||||
xf86Screens[i]->entityInstanceList[j]);
|
||||
|
||||
if (dev == layout->screen->device) {
|
||||
/* A match has been found */
|
||||
xf86Screens[i]->confScreen = layout->screen;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
if (layout->screen == NULL) {
|
||||
layout = xf86BusConfigMatch(xf86Screens[i], FALSE);
|
||||
if (layout && layout->screen)
|
||||
xf86Screens[i]->confScreen = layout->screen;
|
||||
else {
|
||||
/* No match found */
|
||||
xf86Msg(X_ERROR,
|
||||
"Screen %d deleted because of no matching config section.\n",
|
||||
|
@ -199,9 +213,12 @@ xf86BusConfig(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* bind GPU conf screen to protocol screen 0 */
|
||||
for (i = 0; i < xf86NumGPUScreens; i++)
|
||||
xf86GPUScreens[i]->confScreen = xf86Screens[0]->confScreen;
|
||||
/* bind GPU conf screen to the configured protocol screen, or 0 if not configured */
|
||||
for (i = 0; i < xf86NumGPUScreens; i++) {
|
||||
layout = xf86BusConfigMatch(xf86GPUScreens[i], TRUE);
|
||||
int scrnum = (layout && layout->screen) ? layout->screen->screennum : 0;
|
||||
xf86GPUScreens[i]->confScreen = xf86Screens[scrnum]->confScreen;
|
||||
}
|
||||
|
||||
/* If no screens left, return now. */
|
||||
if (xf86NumScreens == 0) {
|
||||
|
|
|
@ -209,9 +209,11 @@ xf86AutoConfigOutputDevices(void)
|
|||
if (!xf86Info.autoBindGPU)
|
||||
return;
|
||||
|
||||
for (i = 0; i < xf86NumGPUScreens; i++)
|
||||
for (i = 0; i < xf86NumGPUScreens; i++) {
|
||||
int scrnum = xf86GPUScreens[i]->confScreen->screennum;
|
||||
RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
|
||||
xf86ScrnToScreen(xf86Screens[0]));
|
||||
xf86ScrnToScreen(xf86Screens[scrnum]));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -689,8 +691,10 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < xf86NumGPUScreens; i++)
|
||||
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
|
||||
for (i = 0; i < xf86NumGPUScreens; i++) {
|
||||
int scrnum = xf86GPUScreens[i]->confScreen->screennum;
|
||||
AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen);
|
||||
}
|
||||
|
||||
xf86AutoConfigOutputDevices();
|
||||
|
||||
|
|
|
@ -608,7 +608,7 @@ xf86platformAddGPUDevices(DriverPtr drvp)
|
|||
int
|
||||
xf86platformAddDevice(int index)
|
||||
{
|
||||
int i, old_screens, scr_index;
|
||||
int i, old_screens, scr_index, scrnum;
|
||||
DriverPtr drvp = NULL;
|
||||
screenLayoutPtr layout;
|
||||
static const char *hotplug_driver_name = "modesetting";
|
||||
|
@ -674,14 +674,15 @@ xf86platformAddDevice(int index)
|
|||
xf86NumGPUScreens = old_screens;
|
||||
return -1;
|
||||
}
|
||||
/* attach unbound to 0 protocol screen */
|
||||
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
|
||||
/* attach unbound to the configured protocol screen (or 0) */
|
||||
scrnum = xf86GPUScreens[i]->confScreen->screennum;
|
||||
AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen);
|
||||
if (xf86Info.autoBindGPU)
|
||||
RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
|
||||
xf86ScrnToScreen(xf86Screens[0]));
|
||||
xf86ScrnToScreen(xf86Screens[scrnum]));
|
||||
|
||||
RRResourcesChanged(xf86Screens[0]->pScreen);
|
||||
RRTellChanged(xf86Screens[0]->pScreen);
|
||||
RRResourcesChanged(xf86Screens[scrnum]->pScreen);
|
||||
RRTellChanged(xf86Screens[scrnum]->pScreen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -690,7 +691,7 @@ void
|
|||
xf86platformRemoveDevice(int index)
|
||||
{
|
||||
EntityPtr entity;
|
||||
int ent_num, i, j;
|
||||
int ent_num, i, j, scrnum;
|
||||
Bool found;
|
||||
|
||||
for (ent_num = 0; ent_num < xf86NumEntities; ent_num++) {
|
||||
|
@ -717,6 +718,8 @@ xf86platformRemoveDevice(int index)
|
|||
goto out;
|
||||
}
|
||||
|
||||
scrnum = xf86GPUScreens[i]->confScreen->screennum;
|
||||
|
||||
xf86GPUScreens[i]->pScreen->CloseScreen(xf86GPUScreens[i]->pScreen);
|
||||
|
||||
RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
|
||||
|
@ -726,8 +729,8 @@ xf86platformRemoveDevice(int index)
|
|||
|
||||
xf86_remove_platform_device(index);
|
||||
|
||||
RRResourcesChanged(xf86Screens[0]->pScreen);
|
||||
RRTellChanged(xf86Screens[0]->pScreen);
|
||||
RRResourcesChanged(xf86Screens[scrnum]->pScreen);
|
||||
RRTellChanged(xf86Screens[scrnum]->pScreen);
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
if build_docs_devel
|
||||
basename = 'ddxDesign'
|
||||
input_xml = basename + '.xml'
|
||||
|
||||
custom_target(
|
||||
basename + '.html',
|
||||
output: basename + '.html',
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
|
||||
'-o', meson.current_build_dir(),
|
||||
'xhtml-nochunks', '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: false,
|
||||
)
|
||||
|
||||
if build_docs_pdf
|
||||
foreach format : ['ps', 'pdf']
|
||||
output_fn = basename + '.' + format
|
||||
custom_target(
|
||||
output_fn,
|
||||
output: output_fn,
|
||||
input: [input_xml],
|
||||
command: [xmlto] + docs_xmlto_search_flags + [
|
||||
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
|
||||
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
|
||||
'-o', meson.current_build_dir(),
|
||||
'--with-fop', format, '@INPUT0@'],
|
||||
build_by_default: true,
|
||||
install: false,
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
endif
|
|
@ -272,6 +272,9 @@ ms_present_check_unflip(RRCrtcPtr crtc,
|
|||
pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
|
||||
return FALSE;
|
||||
|
||||
if (!ms->drmmode.glamor)
|
||||
return FALSE;
|
||||
|
||||
#ifdef GBM_BO_WITH_MODIFIERS
|
||||
/* Check if buffer format/modifier is supported by all active CRTCs */
|
||||
gbm = ms->glamor.gbm_bo_from_pixmap(screen, pixmap);
|
||||
|
|
|
@ -171,15 +171,6 @@ if get_option('suid_wrapper')
|
|||
)
|
||||
endif
|
||||
|
||||
executable('cvt',
|
||||
['utils/cvt/cvt.c', 'modes/xf86cvt.c'],
|
||||
include_directories: [inc, xorg_inc],
|
||||
dependencies: xorg_deps,
|
||||
link_with: libxserver_os,
|
||||
c_args: xorg_c_args,
|
||||
install: true,
|
||||
)
|
||||
|
||||
executable('gtf',
|
||||
'utils/gtf/gtf.c',
|
||||
include_directories: [inc, xorg_inc],
|
||||
|
@ -234,14 +225,10 @@ install_man(configure_file(
|
|||
configuration: manpage_config,
|
||||
))
|
||||
|
||||
install_man(configure_file(
|
||||
input: 'utils/man/cvt.man',
|
||||
output: 'cvt.1',
|
||||
configuration: manpage_config,
|
||||
))
|
||||
|
||||
install_man(configure_file(
|
||||
input: 'utils/man/gtf.man',
|
||||
output: 'gtf.1',
|
||||
configuration: manpage_config,
|
||||
))
|
||||
|
||||
subdir('doc')
|
||||
|
|
|
@ -8,7 +8,6 @@ libxf86modes_la_SOURCES = \
|
|||
xf86Crtc.c \
|
||||
xf86Crtc.h \
|
||||
xf86Cursors.c \
|
||||
xf86cvt.c \
|
||||
xf86gtf.c \
|
||||
xf86EdidModes.c \
|
||||
xf86Modes.c \
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
srcs_xorg_modes = [
|
||||
'xf86Crtc.c',
|
||||
'xf86Cursors.c',
|
||||
'xf86cvt.c',
|
||||
'xf86gtf.c',
|
||||
'xf86EdidModes.c',
|
||||
'xf86Modes.c',
|
||||
|
@ -15,8 +14,8 @@ endif
|
|||
|
||||
xorg_modes = static_library('xorg_modes',
|
||||
srcs_xorg_modes,
|
||||
include_directories: [inc, xorg_inc],
|
||||
dependencies: common_dep,
|
||||
include_directories: [ inc, xorg_inc ],
|
||||
dependencies: [ common_dep, libxcvt_dep ],
|
||||
c_args: xorg_c_args,
|
||||
)
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <libxcvt/libxcvt.h>
|
||||
#include "xf86Modes.h"
|
||||
#include "xf86Priv.h"
|
||||
|
||||
|
@ -792,3 +793,33 @@ xf86PruneDuplicateModes(DisplayModePtr modes)
|
|||
|
||||
return modes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
|
||||
*/
|
||||
DisplayModePtr
|
||||
xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
|
||||
Bool Interlaced)
|
||||
{
|
||||
struct libxcvt_mode_info *libxcvt_mode_info;
|
||||
DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
|
||||
|
||||
libxcvt_mode_info =
|
||||
libxcvt_gen_mode_info(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
|
||||
|
||||
Mode->VDisplay = libxcvt_mode_info->vdisplay;
|
||||
Mode->HDisplay = libxcvt_mode_info->hdisplay;
|
||||
Mode->Clock = libxcvt_mode_info->dot_clock;
|
||||
Mode->HSyncStart = libxcvt_mode_info->hsync_start;
|
||||
Mode->HSyncEnd = libxcvt_mode_info->hsync_end;
|
||||
Mode->HTotal = libxcvt_mode_info->htotal;
|
||||
Mode->VSyncStart = libxcvt_mode_info->vsync_start;
|
||||
Mode->VSyncEnd = libxcvt_mode_info->vsync_end;
|
||||
Mode->VTotal = libxcvt_mode_info->vtotal;
|
||||
Mode->VRefresh = libxcvt_mode_info->vrefresh;
|
||||
Mode->Flags = libxcvt_mode_info->mode_flags;
|
||||
|
||||
free(libxcvt_mode_info);
|
||||
|
||||
return Mode;
|
||||
}
|
||||
|
|
|
@ -1,295 +0,0 @@
|
|||
/*
|
||||
* Copyright 2005-2006 Luc Verhaegen.
|
||||
*
|
||||
* 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The reason for having this function in a file of its own is
|
||||
* so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
|
||||
* code is shared directly.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_XORG_CONFIG_H
|
||||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include "xf86.h"
|
||||
#include "xf86Modes.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
|
||||
*
|
||||
* These calculations are stolen from the CVT calculation spreadsheet written
|
||||
* by Graham Loveridge. He seems to be claiming no copyright and there seems to
|
||||
* be no license attached to this. He apparently just wants to see his name
|
||||
* mentioned.
|
||||
*
|
||||
* This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
|
||||
*
|
||||
* Comments and structure corresponds to the comments and structure of the xls.
|
||||
* This should ease importing of future changes to the standard (not very
|
||||
* likely though).
|
||||
*
|
||||
* About margins; i'm sure that they are to be the bit between HDisplay and
|
||||
* HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and
|
||||
* VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
|
||||
* outside sync "margin" for some reason. Since we prefer seeing proper
|
||||
* blanking instead of the overscan colour, and since the Crtc* values will
|
||||
* probably get altered after us, we will disable margins altogether. With
|
||||
* these calculations, Margins will plainly expand H/VDisplay, and we don't
|
||||
* want that. -- libv
|
||||
*
|
||||
*/
|
||||
DisplayModePtr
|
||||
xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
|
||||
Bool Interlaced)
|
||||
{
|
||||
DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
|
||||
|
||||
/* 1) top/bottom margin size (% of height) - default: 1.8 */
|
||||
#define CVT_MARGIN_PERCENTAGE 1.8
|
||||
|
||||
/* 2) character cell horizontal granularity (pixels) - default 8 */
|
||||
#define CVT_H_GRANULARITY 8
|
||||
|
||||
/* 4) Minimum vertical porch (lines) - default 3 */
|
||||
#define CVT_MIN_V_PORCH 3
|
||||
|
||||
/* 4) Minimum number of vertical back porch lines - default 6 */
|
||||
#define CVT_MIN_V_BPORCH 6
|
||||
|
||||
/* Pixel Clock step (kHz) */
|
||||
#define CVT_CLOCK_STEP 250
|
||||
|
||||
Bool Margins = FALSE;
|
||||
float VFieldRate, HPeriod;
|
||||
int HDisplayRnd, HMargin;
|
||||
int VDisplayRnd, VMargin, VSync;
|
||||
float Interlace; /* Please rename this */
|
||||
char *tmp;
|
||||
|
||||
/* CVT default is 60.0Hz */
|
||||
if (!VRefresh)
|
||||
VRefresh = 60.0;
|
||||
|
||||
/* 1. Required field rate */
|
||||
if (Interlaced)
|
||||
VFieldRate = VRefresh * 2;
|
||||
else
|
||||
VFieldRate = VRefresh;
|
||||
|
||||
/* 2. Horizontal pixels */
|
||||
HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
|
||||
|
||||
/* 3. Determine left and right borders */
|
||||
if (Margins) {
|
||||
/* right margin is actually exactly the same as left */
|
||||
HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
|
||||
HMargin -= HMargin % CVT_H_GRANULARITY;
|
||||
}
|
||||
else
|
||||
HMargin = 0;
|
||||
|
||||
/* 4. Find total active pixels */
|
||||
Mode->HDisplay = HDisplayRnd + 2 * HMargin;
|
||||
|
||||
/* 5. Find number of lines per field */
|
||||
if (Interlaced)
|
||||
VDisplayRnd = VDisplay / 2;
|
||||
else
|
||||
VDisplayRnd = VDisplay;
|
||||
|
||||
/* 6. Find top and bottom margins */
|
||||
/* nope. */
|
||||
if (Margins)
|
||||
/* top and bottom margins are equal again. */
|
||||
VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
|
||||
else
|
||||
VMargin = 0;
|
||||
|
||||
Mode->VDisplay = VDisplay + 2 * VMargin;
|
||||
|
||||
/* 7. Interlace */
|
||||
if (Interlaced)
|
||||
Interlace = 0.5;
|
||||
else
|
||||
Interlace = 0.0;
|
||||
|
||||
/* Determine VSync Width from aspect ratio */
|
||||
if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
|
||||
VSync = 4;
|
||||
else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
|
||||
VSync = 5;
|
||||
else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
|
||||
VSync = 6;
|
||||
else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
|
||||
VSync = 7;
|
||||
else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
|
||||
VSync = 7;
|
||||
else /* Custom */
|
||||
VSync = 10;
|
||||
|
||||
if (!Reduced) { /* simplified GTF calculation */
|
||||
|
||||
/* 4) Minimum time of vertical sync + back porch interval (µs)
|
||||
* default 550.0 */
|
||||
#define CVT_MIN_VSYNC_BP 550.0
|
||||
|
||||
/* 3) Nominal HSync width (% of line period) - default 8 */
|
||||
#define CVT_HSYNC_PERCENTAGE 8
|
||||
|
||||
float HBlankPercentage;
|
||||
int VSyncAndBackPorch, VBackPorch;
|
||||
int HBlank;
|
||||
|
||||
/* 8. Estimated Horizontal period */
|
||||
HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) /
|
||||
(VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
|
||||
|
||||
/* 9. Find number of lines in sync + backporch */
|
||||
if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) <
|
||||
(VSync + CVT_MIN_V_PORCH))
|
||||
VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
|
||||
else
|
||||
VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1;
|
||||
|
||||
/* 10. Find number of lines in back porch */
|
||||
VBackPorch = VSyncAndBackPorch - VSync;
|
||||
(void) VBackPorch;
|
||||
|
||||
/* 11. Find total number of lines in vertical field */
|
||||
Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
|
||||
+ CVT_MIN_V_PORCH;
|
||||
|
||||
/* 5) Definition of Horizontal blanking time limitation */
|
||||
/* Gradient (%/kHz) - default 600 */
|
||||
#define CVT_M_FACTOR 600
|
||||
|
||||
/* Offset (%) - default 40 */
|
||||
#define CVT_C_FACTOR 40
|
||||
|
||||
/* Blanking time scaling factor - default 128 */
|
||||
#define CVT_K_FACTOR 128
|
||||
|
||||
/* Scaling factor weighting - default 20 */
|
||||
#define CVT_J_FACTOR 20
|
||||
|
||||
#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
|
||||
#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
|
||||
CVT_J_FACTOR
|
||||
|
||||
/* 12. Find ideal blanking duty cycle from formula */
|
||||
HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0;
|
||||
|
||||
/* 13. Blanking time */
|
||||
if (HBlankPercentage < 20)
|
||||
HBlankPercentage = 20;
|
||||
|
||||
HBlank = Mode->HDisplay * HBlankPercentage / (100.0 - HBlankPercentage);
|
||||
HBlank -= HBlank % (2 * CVT_H_GRANULARITY);
|
||||
|
||||
/* 14. Find total number of pixels in a line. */
|
||||
Mode->HTotal = Mode->HDisplay + HBlank;
|
||||
|
||||
/* Fill in HSync values */
|
||||
Mode->HSyncEnd = Mode->HDisplay + HBlank / 2;
|
||||
|
||||
Mode->HSyncStart = Mode->HSyncEnd -
|
||||
(Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100;
|
||||
Mode->HSyncStart += CVT_H_GRANULARITY -
|
||||
Mode->HSyncStart % CVT_H_GRANULARITY;
|
||||
|
||||
/* Fill in VSync values */
|
||||
Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH;
|
||||
Mode->VSyncEnd = Mode->VSyncStart + VSync;
|
||||
|
||||
}
|
||||
else { /* Reduced blanking */
|
||||
/* Minimum vertical blanking interval time (µs) - default 460 */
|
||||
#define CVT_RB_MIN_VBLANK 460.0
|
||||
|
||||
/* Fixed number of clocks for horizontal sync */
|
||||
#define CVT_RB_H_SYNC 32.0
|
||||
|
||||
/* Fixed number of clocks for horizontal blanking */
|
||||
#define CVT_RB_H_BLANK 160.0
|
||||
|
||||
/* Fixed number of lines for vertical front porch - default 3 */
|
||||
#define CVT_RB_VFPORCH 3
|
||||
|
||||
int VBILines;
|
||||
|
||||
/* 8. Estimate Horizontal period. */
|
||||
HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) /
|
||||
(VDisplayRnd + 2 * VMargin);
|
||||
|
||||
/* 9. Find number of lines in vertical blanking */
|
||||
VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
|
||||
|
||||
/* 10. Check if vertical blanking is sufficient */
|
||||
if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
|
||||
VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
|
||||
|
||||
/* 11. Find total number of lines in vertical field */
|
||||
Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
|
||||
|
||||
/* 12. Find total number of pixels in a line */
|
||||
Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK;
|
||||
|
||||
/* Fill in HSync values */
|
||||
Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2;
|
||||
Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC;
|
||||
|
||||
/* Fill in VSync values */
|
||||
Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH;
|
||||
Mode->VSyncEnd = Mode->VSyncStart + VSync;
|
||||
}
|
||||
|
||||
/* 15/13. Find pixel clock frequency (kHz for xf86) */
|
||||
Mode->Clock = Mode->HTotal * 1000.0 / HPeriod;
|
||||
Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP;
|
||||
|
||||
/* 16/14. Find actual Horizontal Frequency (kHz) */
|
||||
Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal);
|
||||
|
||||
/* 17/15. Find actual Field rate */
|
||||
Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
|
||||
((float) (Mode->HTotal * Mode->VTotal));
|
||||
|
||||
/* 18/16. Find actual vertical frame frequency */
|
||||
/* ignore - just set the mode flag for interlaced */
|
||||
if (Interlaced)
|
||||
Mode->VTotal *= 2;
|
||||
|
||||
XNFasprintf(&tmp, "%dx%d", HDisplay, VDisplay);
|
||||
Mode->name = tmp;
|
||||
|
||||
if (Reduced)
|
||||
Mode->Flags |= V_PHSYNC | V_NVSYNC;
|
||||
else
|
||||
Mode->Flags |= V_NHSYNC | V_PVSYNC;
|
||||
|
||||
if (Interlaced)
|
||||
Mode->Flags |= V_INTERLACE;
|
||||
|
||||
return Mode;
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
SUBDIRS = \
|
||||
gtf \
|
||||
cvt \
|
||||
man
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
cvt
|
|
@ -1,35 +0,0 @@
|
|||
# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
bin_PROGRAMS = cvt
|
||||
|
||||
AM_CPPFLAGS = $(XORG_INCS) \
|
||||
-I$(top_srcdir)/hw/xfree86/ddc \
|
||||
-I$(top_srcdir)/hw/xfree86/modes \
|
||||
-I$(top_srcdir)/hw/xfree86/parser
|
||||
|
||||
# gah
|
||||
cvt_SOURCES = cvt.c \
|
||||
$(top_srcdir)/hw/xfree86/modes/xf86cvt.c \
|
||||
$(top_srcdir)/os/xprintf.c
|
||||
|
||||
cvt_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
|
|
@ -1,294 +0,0 @@
|
|||
/*
|
||||
* Copyright 2005-2006 Luc Verhaegen.
|
||||
*
|
||||
* 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standalone VESA CVT standard timing modelines generator. */
|
||||
|
||||
#include "xf86.h"
|
||||
#include "xf86Modes.h"
|
||||
|
||||
/* FatalError implementation used by the server code we built in */
|
||||
void
|
||||
FatalError(const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, f);
|
||||
vfprintf(stderr, f, args);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* xnfalloc implementation used by the server code we built in */
|
||||
void *
|
||||
XNFalloc(unsigned long n)
|
||||
{
|
||||
void *r;
|
||||
|
||||
r = malloc(n);
|
||||
if (!r) {
|
||||
perror("malloc failed");
|
||||
exit(1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* xnfcalloc implementation used by the server code we built in */
|
||||
void *
|
||||
XNFcallocarray(size_t nmemb, size_t size)
|
||||
{
|
||||
void *r;
|
||||
|
||||
r = calloc(nmemb, size);
|
||||
if (!r) {
|
||||
perror("calloc failed");
|
||||
exit(1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Quickly check whether this is a CVT standard mode.
|
||||
*/
|
||||
static Bool
|
||||
CVTCheckStandard(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
|
||||
Bool Verbose)
|
||||
{
|
||||
Bool IsCVT = TRUE;
|
||||
|
||||
if ((!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) ||
|
||||
(!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) ||
|
||||
(!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) ||
|
||||
(!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) ||
|
||||
(!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)));
|
||||
else {
|
||||
if (Verbose)
|
||||
fprintf(stderr, "Warning: Aspect Ratio is not CVT standard.\n");
|
||||
IsCVT = FALSE;
|
||||
}
|
||||
|
||||
if ((VRefresh != 50.0) && (VRefresh != 60.0) &&
|
||||
(VRefresh != 75.0) && (VRefresh != 85.0)) {
|
||||
if (Verbose)
|
||||
fprintf(stderr, "Warning: Refresh Rate is not CVT standard "
|
||||
"(50, 60, 75 or 85Hz).\n");
|
||||
IsCVT = FALSE;
|
||||
}
|
||||
|
||||
return IsCVT;
|
||||
}
|
||||
|
||||
/*
|
||||
* I'm not documenting --interlaced for obvious reasons, even though I did
|
||||
* implement it. I also can't deny having looked at gtf here.
|
||||
*/
|
||||
static void
|
||||
PrintUsage(char *Name)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "usage: %s [-v|--verbose] [-r|--reduced] X Y [refresh]\n",
|
||||
Name);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -v|--verbose : Warn about CVT standard adherence.\n");
|
||||
fprintf(stderr, " -r|--reduced : Create a mode with reduced blanking "
|
||||
"(default: normal blanking).\n");
|
||||
fprintf(stderr, " X : Desired horizontal resolution "
|
||||
"(multiple of 8, required).\n");
|
||||
fprintf(stderr,
|
||||
" Y : Desired vertical resolution (required).\n");
|
||||
fprintf(stderr,
|
||||
" refresh : Desired refresh rate (default: 60.0Hz).\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Calculates VESA CVT (Coordinated Video Timing) modelines"
|
||||
" for use with X.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void
|
||||
PrintComment(DisplayModeRec * Mode, Bool CVT, Bool Reduced)
|
||||
{
|
||||
printf("# %dx%d %.2f Hz ", Mode->HDisplay, Mode->VDisplay, Mode->VRefresh);
|
||||
|
||||
if (CVT) {
|
||||
printf("(CVT %.2fM",
|
||||
((float) Mode->HDisplay * Mode->VDisplay) / 1000000.0);
|
||||
|
||||
if (!(Mode->VDisplay % 3) &&
|
||||
((Mode->VDisplay * 4 / 3) == Mode->HDisplay))
|
||||
printf("3");
|
||||
else if (!(Mode->VDisplay % 9) &&
|
||||
((Mode->VDisplay * 16 / 9) == Mode->HDisplay))
|
||||
printf("9");
|
||||
else if (!(Mode->VDisplay % 10) &&
|
||||
((Mode->VDisplay * 16 / 10) == Mode->HDisplay))
|
||||
printf("A");
|
||||
else if (!(Mode->VDisplay % 4) &&
|
||||
((Mode->VDisplay * 5 / 4) == Mode->HDisplay))
|
||||
printf("4");
|
||||
else if (!(Mode->VDisplay % 9) &&
|
||||
((Mode->VDisplay * 15 / 9) == Mode->HDisplay))
|
||||
printf("9");
|
||||
|
||||
if (Reduced)
|
||||
printf("-R");
|
||||
|
||||
printf(") ");
|
||||
}
|
||||
else
|
||||
printf("(CVT) ");
|
||||
|
||||
printf("hsync: %.2f kHz; ", Mode->HSync);
|
||||
printf("pclk: %.2f MHz", ((float) Mode->Clock) / 1000.0);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Originally grabbed from xf86Mode.c.
|
||||
*
|
||||
* Ignoring the actual Mode->name, as the user will want something solid
|
||||
* to grab hold of.
|
||||
*/
|
||||
static void
|
||||
PrintModeline(DisplayModePtr Mode, int HDisplay, int VDisplay, float VRefresh,
|
||||
Bool Reduced)
|
||||
{
|
||||
if (Reduced)
|
||||
printf("Modeline \"%dx%dR\" ", HDisplay, VDisplay);
|
||||
else
|
||||
printf("Modeline \"%dx%d_%.2f\" ", HDisplay, VDisplay, VRefresh);
|
||||
|
||||
printf("%6.2f %i %i %i %i %i %i %i %i", Mode->Clock / 1000.,
|
||||
Mode->HDisplay, Mode->HSyncStart, Mode->HSyncEnd, Mode->HTotal,
|
||||
Mode->VDisplay, Mode->VSyncStart, Mode->VSyncEnd, Mode->VTotal);
|
||||
|
||||
if (Mode->Flags & V_INTERLACE)
|
||||
printf(" interlace");
|
||||
if (Mode->Flags & V_PHSYNC)
|
||||
printf(" +hsync");
|
||||
if (Mode->Flags & V_NHSYNC)
|
||||
printf(" -hsync");
|
||||
if (Mode->Flags & V_PVSYNC)
|
||||
printf(" +vsync");
|
||||
if (Mode->Flags & V_NVSYNC)
|
||||
printf(" -vsync");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
DisplayModeRec *Mode;
|
||||
int HDisplay = 0, VDisplay = 0;
|
||||
float VRefresh = 0.0;
|
||||
Bool Reduced = FALSE, Verbose = FALSE, IsCVT;
|
||||
Bool Interlaced = FALSE;
|
||||
int n;
|
||||
|
||||
if ((argc < 3) || (argc > 7)) {
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This doesn't filter out bad flags properly. Bad flags get passed down
|
||||
* to atoi/atof, which then return 0, so that these variables can get
|
||||
* filled next time round. So this is just a cosmetic problem.
|
||||
*/
|
||||
for (n = 1; n < argc; n++) {
|
||||
if (!strcmp(argv[n], "-r") || !strcmp(argv[n], "--reduced"))
|
||||
Reduced = TRUE;
|
||||
else if (!strcmp(argv[n], "-i") || !strcmp(argv[n], "--interlaced"))
|
||||
Interlaced = TRUE;
|
||||
else if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--verbose"))
|
||||
Verbose = TRUE;
|
||||
else if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help")) {
|
||||
PrintUsage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
else if (!HDisplay) {
|
||||
HDisplay = atoi(argv[n]);
|
||||
if (!HDisplay) {
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (!VDisplay) {
|
||||
VDisplay = atoi(argv[n]);
|
||||
if (!VDisplay) {
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (!VRefresh) {
|
||||
VRefresh = atof(argv[n]);
|
||||
if (!VRefresh) {
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PrintUsage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!HDisplay || !VDisplay) {
|
||||
PrintUsage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Default to 60.0Hz */
|
||||
if (!VRefresh)
|
||||
VRefresh = 60.0;
|
||||
|
||||
/* Horizontal timing is always a multiple of 8: round up. */
|
||||
if (HDisplay & 0x07) {
|
||||
HDisplay &= ~0x07;
|
||||
HDisplay += 8;
|
||||
}
|
||||
|
||||
if (Reduced) {
|
||||
if ((VRefresh / 60.0) != floor(VRefresh / 60.0)) {
|
||||
fprintf(stderr,
|
||||
"\nERROR: Multiple of 60Hz refresh rate required for "
|
||||
" reduced blanking.\n");
|
||||
PrintUsage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
IsCVT = CVTCheckStandard(HDisplay, VDisplay, VRefresh, Reduced, Verbose);
|
||||
|
||||
Mode = xf86CVTMode(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
|
||||
|
||||
PrintComment(Mode, IsCVT, Reduced);
|
||||
PrintModeline(Mode, HDisplay, VDisplay, VRefresh, Reduced);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,2 +1,2 @@
|
|||
include $(top_srcdir)/manpages.am
|
||||
appman_PRE = cvt.man gtf.man
|
||||
appman_PRE = gtf.man
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
.TH CVT 1 @vendorversion@
|
||||
.SH NAME
|
||||
cvt - calculate VESA CVT mode lines
|
||||
.SH SYNOPSIS
|
||||
.B cvt
|
||||
.RB [ \-v | \-\-verbose ]
|
||||
.RB [ \-r | \-\-reduced ]
|
||||
.I h-resolution
|
||||
.I v-resolution
|
||||
.RB [ refresh ]
|
||||
.SH DESCRIPTION
|
||||
.I Cvt
|
||||
is a utility for calculating VESA Coordinated Video Timing modes. Given the
|
||||
desired horizontal and vertical resolutions, a modeline adhering to the CVT
|
||||
standard is printed. This modeline can be included in Xorg
|
||||
.B xorg.conf(@filemansuffix@)
|
||||
.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP 8
|
||||
.BR refresh
|
||||
Provide a vertical refresh rate in Hz. The CVT standard prefers either 50.0,
|
||||
60.0, 75.0 or 85.0Hz. The default is 60.0Hz.
|
||||
.TP 8
|
||||
.BR \-v | \-\-verbose
|
||||
Warn verbosely when a given mode does not completely correspond with CVT
|
||||
standards.
|
||||
.TP 8
|
||||
.BR \-r | \-\-reduced
|
||||
Create a mode with reduced blanking. This allows for higher frequency signals,
|
||||
with a lower or equal dotclock. Not for Cathode Ray Tube based displays though.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
xorg.conf(@filemansuffix@), gtf(@appmansuffix@)
|
||||
.SH AUTHOR
|
||||
Luc Verhaegen.
|
||||
.PP
|
||||
This program is based on the Coordinated Video Timing sample
|
||||
implementation written by Graham Loveridge. This file is publicly
|
||||
available at <http://www.vesa.org/Public/CVT/CVTd6r1.xls>. CVT is a
|
||||
VESA trademark.
|
|
@ -12,7 +12,8 @@ Xwayland_CFLAGS = \
|
|||
$(XWAYLANDMODULES_CFLAGS) \
|
||||
$(DIX_CFLAGS) \
|
||||
$(GLAMOR_CFLAGS) \
|
||||
$(GBM_CFLAGS)
|
||||
$(GBM_CFLAGS) \
|
||||
$(LIBXCVT_CFLAGS)
|
||||
|
||||
Xwayland_SOURCES = \
|
||||
xwayland.c \
|
||||
|
@ -60,7 +61,8 @@ Xwayland_LDADD = \
|
|||
$(GLXVND_LIB) \
|
||||
$(XWAYLAND_SYS_LIBS) \
|
||||
$(top_builddir)/Xext/libXvidmode.la \
|
||||
$(XSERVER_SYS_LIBS)
|
||||
$(XSERVER_SYS_LIBS) \
|
||||
$(LIBXCVT_LIBS)
|
||||
Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
|
||||
|
||||
Xwayland_built_sources =
|
||||
|
|
|
@ -171,6 +171,8 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
|||
}
|
||||
|
||||
wl_surface_attach(xwl_cursor->surface, buffer, 0, 0);
|
||||
wl_surface_set_buffer_scale(xwl_cursor->surface,
|
||||
xwl_seat->xwl_screen->global_output_scale);
|
||||
xwl_surface_damage(xwl_seat->xwl_screen, xwl_cursor->surface, 0, 0,
|
||||
xwl_seat->x_cursor->bits->width,
|
||||
xwl_seat->x_cursor->bits->height);
|
||||
|
@ -190,6 +192,7 @@ xwl_cursor_attach_pixmap(struct xwl_seat *xwl_seat,
|
|||
void
|
||||
xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_cursor *xwl_cursor = &xwl_seat->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
|
@ -220,8 +223,8 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
|
|||
wl_pointer_set_cursor(xwl_seat->wl_pointer,
|
||||
xwl_seat->pointer_enter_serial,
|
||||
xwl_cursor->surface,
|
||||
xwl_seat->x_cursor->bits->xhot,
|
||||
xwl_seat->x_cursor->bits->yhot);
|
||||
xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot),
|
||||
xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot));
|
||||
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
@ -230,6 +233,7 @@ void
|
|||
xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
struct xwl_screen *xwl_screen = xwl_seat->xwl_screen;
|
||||
struct xwl_cursor *xwl_cursor = &xwl_tablet_tool->cursor;
|
||||
PixmapPtr pixmap;
|
||||
CursorPtr cursor;
|
||||
|
@ -258,9 +262,9 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
|
|||
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
|
||||
xwl_tablet_tool->proximity_in_serial,
|
||||
xwl_cursor->surface,
|
||||
xwl_seat->x_cursor->bits->xhot,
|
||||
xwl_seat->x_cursor->bits->yhot);
|
||||
|
||||
xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->xhot),
|
||||
xwl_scale_to(xwl_screen, xwl_seat->x_cursor->bits->yhot));
|
||||
wl_surface_set_buffer_scale(xwl_cursor->surface, xwl_screen->global_output_scale);
|
||||
xwl_cursor_attach_pixmap(xwl_seat, xwl_cursor, pixmap);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* Copied from hw/xfree86/modes/xf86cvt.c into xwayland DDX and
|
||||
* changed to generate an RRMode */
|
||||
|
||||
/*
|
||||
* Copyright 2005-2006 Luc Verhaegen.
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,284 +21,38 @@
|
|||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The reason for having this function in a file of its own is
|
||||
* so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
|
||||
* code is shared directly.
|
||||
*/
|
||||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <randrstr.h>
|
||||
#include <libxcvt/libxcvt.h>
|
||||
|
||||
#include "xwayland-cvt.h"
|
||||
|
||||
/*
|
||||
* Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
|
||||
*
|
||||
* These calculations are stolen from the CVT calculation spreadsheet written
|
||||
* by Graham Loveridge. He seems to be claiming no copyright and there seems to
|
||||
* be no license attached to this. He apparently just wants to see his name
|
||||
* mentioned.
|
||||
*
|
||||
* This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
|
||||
*
|
||||
* Comments and structure corresponds to the comments and structure of the xls.
|
||||
* This should ease importing of future changes to the standard (not very
|
||||
* likely though).
|
||||
*
|
||||
* About margins; i'm sure that they are to be the bit between HDisplay and
|
||||
* HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and
|
||||
* VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
|
||||
* outside sync "margin" for some reason. Since we prefer seeing proper
|
||||
* blanking instead of the overscan colour, and since the Crtc* values will
|
||||
* probably get altered after us, we will disable margins altogether. With
|
||||
* these calculations, Margins will plainly expand H/VDisplay, and we don't
|
||||
* want that. -- libv
|
||||
*
|
||||
*/
|
||||
RRModePtr
|
||||
xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
|
||||
Bool Interlaced)
|
||||
xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced,
|
||||
Bool interlaced)
|
||||
{
|
||||
/* 1) top/bottom margin size (% of height) - default: 1.8 */
|
||||
#define CVT_MARGIN_PERCENTAGE 1.8
|
||||
|
||||
/* 2) character cell horizontal granularity (pixels) - default 8 */
|
||||
#define CVT_H_GRANULARITY 8
|
||||
|
||||
/* 4) Minimum vertical porch (lines) - default 3 */
|
||||
#define CVT_MIN_V_PORCH 3
|
||||
|
||||
/* 4) Minimum number of vertical back porch lines - default 6 */
|
||||
#define CVT_MIN_V_BPORCH 6
|
||||
|
||||
/* Pixel Clock step (kHz) */
|
||||
#define CVT_CLOCK_STEP 250
|
||||
|
||||
Bool Margins = FALSE;
|
||||
float VFieldRate, HPeriod;
|
||||
int HDisplayRnd, HMargin;
|
||||
int VDisplayRnd, VMargin, VSync;
|
||||
float Interlace; /* Please rename this */
|
||||
struct libxcvt_mode_info *libxcvt_mode_info;
|
||||
char name[128];
|
||||
xRRModeInfo modeinfo;
|
||||
|
||||
libxcvt_mode_info =
|
||||
libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced);
|
||||
|
||||
memset(&modeinfo, 0, sizeof modeinfo);
|
||||
modeinfo.width = libxcvt_mode_info->hdisplay;
|
||||
modeinfo.height = libxcvt_mode_info->vdisplay;
|
||||
modeinfo.dotClock = libxcvt_mode_info->dot_clock * 1000.0;
|
||||
modeinfo.hSyncStart = libxcvt_mode_info->hsync_start;
|
||||
modeinfo.hSyncEnd = libxcvt_mode_info->hsync_end;
|
||||
modeinfo.hTotal = libxcvt_mode_info->htotal;
|
||||
modeinfo.vSyncStart = libxcvt_mode_info->vsync_start;
|
||||
modeinfo.vSyncEnd = libxcvt_mode_info->vsync_end;
|
||||
modeinfo.vTotal = libxcvt_mode_info->vtotal;
|
||||
modeinfo.modeFlags = libxcvt_mode_info->mode_flags;
|
||||
|
||||
/* CVT default is 60.0Hz */
|
||||
if (!VRefresh)
|
||||
VRefresh = 60.0;
|
||||
|
||||
/* 1. Required field rate */
|
||||
if (Interlaced)
|
||||
VFieldRate = VRefresh * 2;
|
||||
else
|
||||
VFieldRate = VRefresh;
|
||||
|
||||
/* 2. Horizontal pixels */
|
||||
HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
|
||||
|
||||
/* 3. Determine left and right borders */
|
||||
if (Margins) {
|
||||
/* right margin is actually exactly the same as left */
|
||||
HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
|
||||
HMargin -= HMargin % CVT_H_GRANULARITY;
|
||||
}
|
||||
else
|
||||
HMargin = 0;
|
||||
|
||||
/* 4. Find total active pixels */
|
||||
modeinfo.width = HDisplayRnd + 2 * HMargin;
|
||||
|
||||
/* 5. Find number of lines per field */
|
||||
if (Interlaced)
|
||||
VDisplayRnd = VDisplay / 2;
|
||||
else
|
||||
VDisplayRnd = VDisplay;
|
||||
|
||||
/* 6. Find top and bottom margins */
|
||||
/* nope. */
|
||||
if (Margins)
|
||||
/* top and bottom margins are equal again. */
|
||||
VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
|
||||
else
|
||||
VMargin = 0;
|
||||
|
||||
modeinfo.height = VDisplay + 2 * VMargin;
|
||||
|
||||
/* 7. Interlace */
|
||||
if (Interlaced)
|
||||
Interlace = 0.5;
|
||||
else
|
||||
Interlace = 0.0;
|
||||
|
||||
/* Determine VSync Width from aspect ratio */
|
||||
if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
|
||||
VSync = 4;
|
||||
else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
|
||||
VSync = 5;
|
||||
else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
|
||||
VSync = 6;
|
||||
else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
|
||||
VSync = 7;
|
||||
else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
|
||||
VSync = 7;
|
||||
else /* Custom */
|
||||
VSync = 10;
|
||||
|
||||
if (!Reduced) { /* simplified GTF calculation */
|
||||
|
||||
/* 4) Minimum time of vertical sync + back porch interval (µs)
|
||||
* default 550.0 */
|
||||
#define CVT_MIN_VSYNC_BP 550.0
|
||||
|
||||
/* 3) Nominal HSync width (% of line period) - default 8 */
|
||||
#define CVT_HSYNC_PERCENTAGE 8
|
||||
|
||||
float HBlankPercentage;
|
||||
int VSyncAndBackPorch, VBackPorch;
|
||||
int HBlank;
|
||||
|
||||
/* 8. Estimated Horizontal period */
|
||||
HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) /
|
||||
(VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
|
||||
|
||||
/* 9. Find number of lines in sync + backporch */
|
||||
if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) <
|
||||
(VSync + CVT_MIN_V_PORCH))
|
||||
VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
|
||||
else
|
||||
VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1;
|
||||
|
||||
/* 10. Find number of lines in back porch */
|
||||
VBackPorch = VSyncAndBackPorch - VSync;
|
||||
(void) VBackPorch;
|
||||
|
||||
/* 11. Find total number of lines in vertical field */
|
||||
modeinfo.vTotal =
|
||||
VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace +
|
||||
CVT_MIN_V_PORCH;
|
||||
|
||||
/* 5) Definition of Horizontal blanking time limitation */
|
||||
/* Gradient (%/kHz) - default 600 */
|
||||
#define CVT_M_FACTOR 600
|
||||
|
||||
/* Offset (%) - default 40 */
|
||||
#define CVT_C_FACTOR 40
|
||||
|
||||
/* Blanking time scaling factor - default 128 */
|
||||
#define CVT_K_FACTOR 128
|
||||
|
||||
/* Scaling factor weighting - default 20 */
|
||||
#define CVT_J_FACTOR 20
|
||||
|
||||
#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
|
||||
#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
|
||||
CVT_J_FACTOR
|
||||
|
||||
/* 12. Find ideal blanking duty cycle from formula */
|
||||
HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0;
|
||||
|
||||
/* 13. Blanking time */
|
||||
if (HBlankPercentage < 20)
|
||||
HBlankPercentage = 20;
|
||||
|
||||
HBlank = modeinfo.width * HBlankPercentage / (100.0 - HBlankPercentage);
|
||||
HBlank -= HBlank % (2 * CVT_H_GRANULARITY);
|
||||
|
||||
/* 14. Find total number of pixels in a line. */
|
||||
modeinfo.hTotal = modeinfo.width + HBlank;
|
||||
|
||||
/* Fill in HSync values */
|
||||
modeinfo.hSyncEnd = modeinfo.width + HBlank / 2;
|
||||
|
||||
modeinfo.hSyncStart = modeinfo.hSyncEnd -
|
||||
(modeinfo.hTotal * CVT_HSYNC_PERCENTAGE) / 100;
|
||||
modeinfo.hSyncStart += CVT_H_GRANULARITY -
|
||||
modeinfo.hSyncStart % CVT_H_GRANULARITY;
|
||||
|
||||
/* Fill in VSync values */
|
||||
modeinfo.vSyncStart = modeinfo.height + CVT_MIN_V_PORCH;
|
||||
modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync;
|
||||
|
||||
}
|
||||
else { /* Reduced blanking */
|
||||
/* Minimum vertical blanking interval time (µs) - default 460 */
|
||||
#define CVT_RB_MIN_VBLANK 460.0
|
||||
|
||||
/* Fixed number of clocks for horizontal sync */
|
||||
#define CVT_RB_H_SYNC 32.0
|
||||
|
||||
/* Fixed number of clocks for horizontal blanking */
|
||||
#define CVT_RB_H_BLANK 160.0
|
||||
|
||||
/* Fixed number of lines for vertical front porch - default 3 */
|
||||
#define CVT_RB_VFPORCH 3
|
||||
|
||||
int VBILines;
|
||||
|
||||
/* 8. Estimate Horizontal period. */
|
||||
HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) /
|
||||
(VDisplayRnd + 2 * VMargin);
|
||||
|
||||
/* 9. Find number of lines in vertical blanking */
|
||||
VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
|
||||
|
||||
/* 10. Check if vertical blanking is sufficient */
|
||||
if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
|
||||
VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
|
||||
|
||||
/* 11. Find total number of lines in vertical field */
|
||||
modeinfo.vTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
|
||||
|
||||
/* 12. Find total number of pixels in a line */
|
||||
modeinfo.hTotal = modeinfo.width + CVT_RB_H_BLANK;
|
||||
|
||||
/* Fill in HSync values */
|
||||
modeinfo.hSyncEnd = modeinfo.width + CVT_RB_H_BLANK / 2;
|
||||
modeinfo.hSyncStart = modeinfo.hSyncEnd - CVT_RB_H_SYNC;
|
||||
|
||||
/* Fill in VSync values */
|
||||
modeinfo.vSyncStart = modeinfo.height + CVT_RB_VFPORCH;
|
||||
modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync;
|
||||
}
|
||||
|
||||
/* 15/13. Find pixel clock frequency (kHz for xf86) */
|
||||
modeinfo.dotClock = modeinfo.hTotal * 1000.0 / HPeriod;
|
||||
modeinfo.dotClock -= modeinfo.dotClock % CVT_CLOCK_STEP;
|
||||
modeinfo.dotClock *= 1000.0;
|
||||
#if 0
|
||||
/* 16/14. Find actual Horizontal Frequency (kHz) */
|
||||
modeinfo.hSync = ((float) modeinfo.dotClock) / ((float) modeinfo.hTotal);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* 17/15. Find actual Field rate */
|
||||
modeinfo.vRefresh = (1000.0 * ((float) modeinfo.dotClock)) /
|
||||
((float) (modeinfo.hTotal * modeinfo.vTotal));
|
||||
#endif
|
||||
|
||||
/* 18/16. Find actual vertical frame frequency */
|
||||
/* ignore - just set the mode flag for interlaced */
|
||||
if (Interlaced)
|
||||
modeinfo.vTotal *= 2;
|
||||
|
||||
if (Reduced)
|
||||
modeinfo.modeFlags |= RR_HSyncPositive | RR_VSyncNegative;
|
||||
else
|
||||
modeinfo.modeFlags |= RR_HSyncNegative | RR_VSyncPositive;
|
||||
|
||||
if (Interlaced)
|
||||
modeinfo.modeFlags |= RR_Interlace;
|
||||
|
||||
/* FWXGA hack adapted from hw/xfree86/modes/xf86EdidModes.c, because you can't say 1366 */
|
||||
if (HDisplay == 1366 && VDisplay == 768) {
|
||||
modeinfo.width = 1366;
|
||||
modeinfo.hSyncStart--;
|
||||
modeinfo.hSyncEnd--;
|
||||
}
|
||||
free(libxcvt_mode_info);
|
||||
|
||||
snprintf(name, sizeof name, "%dx%d",
|
||||
modeinfo.width, modeinfo.height);
|
||||
|
|
|
@ -60,8 +60,6 @@ struct xwl_eglstream_private {
|
|||
|
||||
EGLConfig config;
|
||||
|
||||
SetWindowPixmapProcPtr SetWindowPixmap;
|
||||
|
||||
Bool have_egl_damage;
|
||||
Bool have_egl_stream_flush;
|
||||
|
||||
|
@ -293,9 +291,11 @@ xwl_eglstream_destroy_pixmap_stream(struct xwl_pixmap *xwl_pixmap)
|
|||
}
|
||||
|
||||
static void
|
||||
xwl_glamor_eglstream_remove_pending_stream(struct xwl_pixmap *xwl_pixmap)
|
||||
xwl_eglstream_destroy_pending_cb(PixmapPtr pixmap)
|
||||
{
|
||||
if (xwl_pixmap->pending_cb) {
|
||||
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
|
||||
if (xwl_pixmap && xwl_pixmap->pending_cb) {
|
||||
wl_callback_destroy(xwl_pixmap->pending_cb);
|
||||
xwl_pixmap->pending_cb = NULL;
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ xwl_glamor_eglstream_destroy_pixmap(PixmapPtr pixmap)
|
|||
struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
|
||||
if (xwl_pixmap && pixmap->refcnt == 1) {
|
||||
xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
|
||||
xwl_eglstream_destroy_pending_cb(pixmap);
|
||||
xwl_eglstream_destroy_pixmap_stream(xwl_pixmap);
|
||||
xwl_pixmap_del_buffer_release_cb(pixmap);
|
||||
}
|
||||
|
@ -325,41 +325,6 @@ xwl_glamor_eglstream_get_wl_buffer_for_pixmap(PixmapPtr pixmap)
|
|||
return xwl_pixmap->buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_eglstream_cancel_pending_stream(PixmapPtr pixmap)
|
||||
{
|
||||
struct xwl_pixmap *xwl_pixmap;
|
||||
|
||||
xwl_pixmap = xwl_pixmap_get(pixmap);
|
||||
if (xwl_pixmap)
|
||||
xwl_glamor_eglstream_remove_pending_stream(xwl_pixmap);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_eglstream_set_window_pixmap(WindowPtr window, PixmapPtr pixmap)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
struct xwl_eglstream_private *xwl_eglstream =
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
PixmapPtr old_pixmap;
|
||||
|
||||
/* The pixmap for this window has changed.
|
||||
* If that occurs while there is a stream pending, i.e. before the
|
||||
* compositor has finished attaching the consumer for the window's
|
||||
* pixmap's original eglstream, then a producer could no longer be
|
||||
* attached, so the stream would be useless.
|
||||
*/
|
||||
old_pixmap = (*screen->GetWindowPixmap) (window);
|
||||
if (old_pixmap && old_pixmap != pixmap)
|
||||
xwl_eglstream_cancel_pending_stream(old_pixmap);
|
||||
|
||||
xwl_screen->screen->SetWindowPixmap = xwl_eglstream->SetWindowPixmap;
|
||||
(*xwl_screen->screen->SetWindowPixmap)(window, pixmap);
|
||||
xwl_eglstream->SetWindowPixmap = xwl_screen->screen->SetWindowPixmap;
|
||||
xwl_screen->screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
|
||||
}
|
||||
|
||||
static const char *
|
||||
xwl_eglstream_get_error_str(EGLint error)
|
||||
{
|
||||
|
@ -449,8 +414,7 @@ xwl_eglstream_consumer_ready_callback(void *data,
|
|||
struct xwl_eglstream_private *xwl_eglstream =
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
|
||||
wl_callback_destroy(callback);
|
||||
xwl_pixmap->pending_cb = NULL;
|
||||
xwl_eglstream_destroy_pending_cb(pixmap);
|
||||
|
||||
xwl_glamor_egl_make_current(xwl_screen);
|
||||
|
||||
|
@ -1109,16 +1073,11 @@ error:
|
|||
static Bool
|
||||
xwl_glamor_eglstream_init_screen(struct xwl_screen *xwl_screen)
|
||||
{
|
||||
struct xwl_eglstream_private *xwl_eglstream =
|
||||
xwl_eglstream_get(xwl_screen);
|
||||
ScreenPtr screen = xwl_screen->screen;
|
||||
|
||||
/* We can just let glamor handle CreatePixmap */
|
||||
screen->DestroyPixmap = xwl_glamor_eglstream_destroy_pixmap;
|
||||
|
||||
xwl_eglstream->SetWindowPixmap = screen->SetWindowPixmap;
|
||||
screen->SetWindowPixmap = xwl_eglstream_set_window_pixmap;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -412,8 +412,8 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
|||
DeviceIntPtr dev = get_pointer_device(xwl_seat);
|
||||
DeviceIntPtr master;
|
||||
int i;
|
||||
int sx = wl_fixed_to_int(sx_w);
|
||||
int sy = wl_fixed_to_int(sy_w);
|
||||
int sx = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
int sy = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
int dx, dy;
|
||||
ScreenPtr pScreen = xwl_seat->xwl_screen->screen;
|
||||
ValuatorMask mask;
|
||||
|
@ -592,13 +592,14 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
|||
uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
int32_t scale = xwl_seat->xwl_screen->global_output_scale;
|
||||
|
||||
if (!xwl_seat->focus_window)
|
||||
return;
|
||||
|
||||
xwl_seat->pending_pointer_event.has_absolute = TRUE;
|
||||
xwl_seat->pending_pointer_event.x = sx_w;
|
||||
xwl_seat->pending_pointer_event.y = sy_w;
|
||||
xwl_seat->pending_pointer_event.x = sx_w * scale;
|
||||
xwl_seat->pending_pointer_event.y = sy_w * scale;
|
||||
|
||||
if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
|
||||
dispatch_pointer_motion_event(xwl_seat);
|
||||
|
@ -672,7 +673,8 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
|||
xorg_list_del(&pending->l);
|
||||
free(pending);
|
||||
} else {
|
||||
valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
|
||||
double scaled_value = wl_fixed_to_double(value);
|
||||
valuator_mask_set_double(&mask, index, scaled_value / divisor);
|
||||
}
|
||||
|
||||
QueuePointerEvents(get_pointer_device(xwl_seat),
|
||||
|
@ -740,12 +742,13 @@ relative_pointer_handle_relative_motion(void *data,
|
|||
wl_fixed_t dy_unaccelf)
|
||||
{
|
||||
struct xwl_seat *xwl_seat = data;
|
||||
int32_t scale = xwl_seat->xwl_screen->global_output_scale;
|
||||
|
||||
xwl_seat->pending_pointer_event.has_relative = TRUE;
|
||||
xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf);
|
||||
xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf);
|
||||
xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf);
|
||||
xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf);
|
||||
xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf) * scale;
|
||||
xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf) * scale;
|
||||
xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf) * scale;
|
||||
xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf) * scale;
|
||||
|
||||
if (!xwl_seat->focus_window)
|
||||
return;
|
||||
|
@ -1057,8 +1060,8 @@ touch_handle_down(void *data, struct wl_touch *wl_touch,
|
|||
|
||||
xwl_touch->window = wl_surface_get_user_data(surface);
|
||||
xwl_touch->id = id;
|
||||
xwl_touch->x = wl_fixed_to_int(sx_w);
|
||||
xwl_touch->y = wl_fixed_to_int(sy_w);
|
||||
xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;
|
||||
xorg_list_add(&xwl_touch->link_touch, &xwl_seat->touches);
|
||||
|
||||
xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchBegin);
|
||||
|
@ -1094,8 +1097,8 @@ touch_handle_motion(void *data, struct wl_touch *wl_touch,
|
|||
if (!xwl_touch)
|
||||
return;
|
||||
|
||||
xwl_touch->x = wl_fixed_to_int(sx_w);
|
||||
xwl_touch->y = wl_fixed_to_int(sy_w);
|
||||
xwl_touch->x = wl_fixed_to_int(sx_w) * xwl_seat->xwl_screen->global_output_scale;;
|
||||
xwl_touch->y = wl_fixed_to_int(sy_w) * xwl_seat->xwl_screen->global_output_scale;;
|
||||
xwl_touch_send_event(xwl_touch, xwl_seat, XI_TouchUpdate);
|
||||
}
|
||||
|
||||
|
@ -1726,8 +1729,8 @@ tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *tool,
|
|||
struct xwl_tablet_tool *xwl_tablet_tool = data;
|
||||
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
|
||||
int32_t dx, dy;
|
||||
double sx = wl_fixed_to_double(x);
|
||||
double sy = wl_fixed_to_double(y);
|
||||
double sx = wl_fixed_to_double(x) * xwl_seat->xwl_screen->global_output_scale;
|
||||
double sy = wl_fixed_to_double(y) * xwl_seat->xwl_screen->global_output_scale;
|
||||
|
||||
if (!xwl_seat->tablet_focus_window)
|
||||
return;
|
||||
|
@ -2714,6 +2717,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em
|
|||
int x,
|
||||
int y)
|
||||
{
|
||||
struct xwl_screen *xwl_screen;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer =
|
||||
warp_emulator->locked_pointer;
|
||||
WindowPtr window;
|
||||
|
@ -2725,6 +2729,7 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em
|
|||
if (!warp_emulator->xwl_seat->focus_window)
|
||||
return;
|
||||
|
||||
xwl_screen = warp_emulator->xwl_seat->xwl_screen;
|
||||
window = warp_emulator->xwl_seat->focus_window->window;
|
||||
if (x >= window->drawable.x ||
|
||||
y >= window->drawable.y ||
|
||||
|
@ -2733,8 +2738,8 @@ xwl_pointer_warp_emulator_set_fake_pos(struct xwl_pointer_warp_emulator *warp_em
|
|||
sx = x - window->drawable.x;
|
||||
sy = y - window->drawable.y;
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(locked_pointer,
|
||||
wl_fixed_from_int(sx),
|
||||
wl_fixed_from_int(sy));
|
||||
wl_fixed_from_int(xwl_scale_to(xwl_screen, sx)),
|
||||
wl_fixed_from_int(xwl_scale_to(xwl_screen, sy)));
|
||||
wl_surface_commit(warp_emulator->xwl_seat->focus_window->surface);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,9 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
|||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
|
||||
width *= xwl_screen->global_output_scale;
|
||||
height *= xwl_screen->global_output_scale;
|
||||
|
||||
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
|
||||
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
|
||||
|
||||
|
@ -216,6 +219,8 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
|||
}
|
||||
|
||||
update_desktop_dimensions();
|
||||
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
}
|
||||
|
||||
struct xwl_emulated_mode *
|
||||
|
@ -495,14 +500,15 @@ xwl_output_set_emulated_mode(struct xwl_output *xwl_output, ClientPtr client,
|
|||
xwl_output_set_randr_emu_props(xwl_output->xwl_screen, client);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_output_change(struct xwl_output *xwl_output)
|
||||
void
|
||||
xwl_output_apply_changes(struct xwl_output *xwl_output)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
struct xwl_output *it;
|
||||
int mode_width, mode_height, count;
|
||||
int width = 0, height = 0, has_this_output = 0;
|
||||
RRModePtr *randr_modes;
|
||||
int32_t scale = xwl_screen->global_output_scale;
|
||||
|
||||
/* Clear out the "done" received flags */
|
||||
xwl_output->wl_output_done = FALSE;
|
||||
|
@ -521,10 +527,10 @@ apply_output_change(struct xwl_output *xwl_output)
|
|||
}
|
||||
|
||||
/* Build a fresh modes array using the current refresh rate */
|
||||
randr_modes = output_get_rr_modes(xwl_output, mode_width, mode_height, &count);
|
||||
randr_modes = output_get_rr_modes(xwl_output, mode_width * scale, mode_height * scale, &count);
|
||||
RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1);
|
||||
RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0],
|
||||
xwl_output->x, xwl_output->y,
|
||||
xwl_output->x * scale, xwl_output->y * scale,
|
||||
xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
|
||||
/* RROutputSetModes takes ownership of the passed in modes, so we only
|
||||
* have to free the pointer array.
|
||||
|
@ -565,7 +571,7 @@ output_handle_done(void *data, struct wl_output *wl_output)
|
|||
*/
|
||||
if (xwl_output->xdg_output_done || !xwl_output->xdg_output ||
|
||||
zxdg_output_v1_get_version(xwl_output->xdg_output) >= 3)
|
||||
apply_output_change(xwl_output);
|
||||
xwl_output_apply_changes(xwl_output);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -608,7 +614,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
|
|||
xwl_output->xdg_output_done = TRUE;
|
||||
if (xwl_output->wl_output_done &&
|
||||
zxdg_output_v1_get_version(xdg_output) < 3)
|
||||
apply_output_change(xwl_output);
|
||||
xwl_output_apply_changes(xwl_output);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -674,6 +680,9 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id)
|
|||
RRCrtcGammaSetSize(xwl_output->randr_crtc, 256);
|
||||
RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1);
|
||||
RROutputSetConnection(xwl_output->randr_output, RR_Connected);
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
|
||||
xwl_output->scale = 1;
|
||||
|
||||
/* We want the output to be in the list as soon as created so we can
|
||||
* use it when binding to the xdg-output protocol...
|
||||
|
@ -698,6 +707,8 @@ err:
|
|||
void
|
||||
xwl_output_destroy(struct xwl_output *xwl_output)
|
||||
{
|
||||
if (xwl_output->xdg_output)
|
||||
zxdg_output_v1_destroy(xwl_output->xdg_output);
|
||||
wl_output_destroy(xwl_output->output);
|
||||
free(xwl_output);
|
||||
}
|
||||
|
@ -717,6 +728,7 @@ xwl_output_remove(struct xwl_output *xwl_output)
|
|||
|
||||
RRCrtcDestroy(xwl_output->randr_crtc);
|
||||
RROutputDestroy(xwl_output->randr_output);
|
||||
RRTellChanged(xwl_screen->screen);
|
||||
|
||||
xwl_output_destroy(xwl_output);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ struct xwl_output {
|
|||
struct xwl_screen *xwl_screen;
|
||||
RROutputPtr randr_output;
|
||||
RRCrtcPtr randr_crtc;
|
||||
int32_t x, y, width, height, refresh;
|
||||
int32_t x, y, width, height, scale, refresh;
|
||||
Rotation rotation;
|
||||
Bool wl_output_done;
|
||||
Bool xdg_output_done;
|
||||
|
@ -77,6 +77,8 @@ void xwl_output_set_emulated_mode(struct xwl_output *xwl_output,
|
|||
void xwl_output_set_window_randr_emu_props(struct xwl_screen *xwl_screen,
|
||||
WindowPtr window);
|
||||
|
||||
void xwl_output_apply_changes(struct xwl_output *xwl_output);
|
||||
|
||||
void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
|
||||
|
||||
#endif /* XWAYLAND_OUTPUT_H */
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include "xwayland-pixmap.h"
|
||||
#include "glamor.h"
|
||||
|
||||
|
||||
#define XWL_PRESENT_CAPS PresentCapabilityAsync
|
||||
|
||||
|
||||
/*
|
||||
* When not flipping let Present copy with 60fps.
|
||||
* When flipping wait on frame_callback, otherwise
|
||||
|
@ -62,13 +66,13 @@ xwl_present_window_get_priv(WindowPtr window)
|
|||
if (!xwl_present_window)
|
||||
return NULL;
|
||||
|
||||
xwl_present_window->window = window;
|
||||
xwl_present_window->msc = 1;
|
||||
xwl_present_window->ust = GetTimeInMicros();
|
||||
|
||||
xorg_list_init(&xwl_present_window->frame_callback_list);
|
||||
xorg_list_init(&xwl_present_window->wait_list);
|
||||
xorg_list_init(&xwl_present_window->release_list);
|
||||
xorg_list_init(&xwl_present_window->flip_queue);
|
||||
xorg_list_init(&xwl_present_window->idle_queue);
|
||||
|
||||
dixSetPrivate(&window->devPrivates,
|
||||
&xwl_present_window_private_key,
|
||||
|
@ -78,6 +82,12 @@ xwl_present_window_get_priv(WindowPtr window)
|
|||
return xwl_present_window;
|
||||
}
|
||||
|
||||
static struct xwl_present_event *
|
||||
xwl_present_event_from_id(uint64_t event_id)
|
||||
{
|
||||
return (struct xwl_present_event*)(uintptr_t)event_id;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
|
@ -90,10 +100,29 @@ xwl_present_timer_callback(OsTimerPtr timer,
|
|||
CARD32 time,
|
||||
void *arg);
|
||||
|
||||
static present_vblank_ptr
|
||||
xwl_present_get_pending_flip(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr flip_pending;
|
||||
|
||||
if (xorg_list_is_empty(&xwl_present_window->flip_queue))
|
||||
return NULL;
|
||||
|
||||
flip_pending = xorg_list_first_entry(&xwl_present_window->flip_queue, present_vblank_rec,
|
||||
event_queue);
|
||||
|
||||
if (flip_pending->queued)
|
||||
return NULL;
|
||||
|
||||
return flip_pending;
|
||||
}
|
||||
|
||||
static inline Bool
|
||||
xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
return !!xwl_present_window->sync_flip ||
|
||||
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
|
||||
return (flip_pending && flip_pending->sync_flip) ||
|
||||
!xorg_list_is_empty(&xwl_present_window->wait_list);
|
||||
}
|
||||
|
||||
|
@ -117,6 +146,58 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
|
||||
|
||||
static uint32_t
|
||||
xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
|
||||
{
|
||||
return XWL_PRESENT_CAPS;
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_present_get_ust_msc(ScreenPtr screen,
|
||||
WindowPtr present_window,
|
||||
uint64_t *ust,
|
||||
uint64_t *msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
if (!xwl_present_window)
|
||||
return BadAlloc;
|
||||
|
||||
*ust = xwl_present_window->ust;
|
||||
*msc = xwl_present_window->msc;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the wait fence or previous flip is completed, it's time
|
||||
* to re-try the request
|
||||
*/
|
||||
static void
|
||||
xwl_present_re_execute(present_vblank_ptr vblank)
|
||||
{
|
||||
uint64_t ust = 0, crtc_msc = 0;
|
||||
|
||||
(void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
|
||||
xwl_present_execute(vblank, ust, crtc_msc);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flip_try_ready(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
|
||||
if (vblank->queued) {
|
||||
xwl_present_re_execute(vblank);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_release_pixmap(struct xwl_present_event *event)
|
||||
{
|
||||
|
@ -131,18 +212,123 @@ xwl_present_release_pixmap(struct xwl_present_event *event)
|
|||
static void
|
||||
xwl_present_free_event(struct xwl_present_event *event)
|
||||
{
|
||||
if (!event)
|
||||
xwl_present_release_pixmap(event);
|
||||
xorg_list_del(&event->vblank.event_queue);
|
||||
present_vblank_destroy(&event->vblank);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_free_idle_vblank(present_vblank_ptr vblank)
|
||||
{
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
xwl_present_free_event(xwl_present_event_from_id((uintptr_t)vblank));
|
||||
}
|
||||
|
||||
static WindowPtr
|
||||
xwl_present_toplvl_pixmap_window(WindowPtr window)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
PixmapPtr pixmap = (*screen->GetWindowPixmap)(window);
|
||||
WindowPtr w = window;
|
||||
WindowPtr next_w;
|
||||
|
||||
while(w->parent) {
|
||||
next_w = w->parent;
|
||||
if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
|
||||
break;
|
||||
}
|
||||
w = next_w;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flips_stop(WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
present_vblank_ptr vblank, tmp;
|
||||
|
||||
/* Change back to the fast refresh rate */
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
|
||||
/* Free any left over idle vblanks */
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue)
|
||||
xwl_present_free_idle_vblank(vblank);
|
||||
|
||||
if (xwl_present_window->flip_active) {
|
||||
xwl_present_free_idle_vblank(xwl_present_window->flip_active);
|
||||
xwl_present_window->flip_active = NULL;
|
||||
}
|
||||
|
||||
xwl_present_flip_try_ready(xwl_present_window);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||
{
|
||||
WindowPtr window = vblank->window;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
|
||||
DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
|
||||
vblank->pixmap ? vblank->pixmap->drawable.id : 0,
|
||||
vblank->window ? vblank->window->drawable.id : 0));
|
||||
|
||||
assert (&vblank->event_queue == xwl_present_window->flip_queue.next);
|
||||
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
|
||||
if (xwl_present_window->flip_active) {
|
||||
struct xwl_present_event *event =
|
||||
xwl_present_event_from_id((uintptr_t)xwl_present_window->flip_active);
|
||||
|
||||
if (!event->pixmap)
|
||||
xwl_present_free_event(event);
|
||||
else
|
||||
/* Put the previous flip in the idle_queue and wait for further notice from
|
||||
* the Wayland compositor
|
||||
*/
|
||||
xorg_list_append(&xwl_present_window->flip_active->event_queue, &xwl_present_window->idle_queue);
|
||||
}
|
||||
|
||||
xwl_present_window->flip_active = vblank;
|
||||
|
||||
present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
|
||||
|
||||
if (vblank->abort_flip)
|
||||
xwl_present_flips_stop(window);
|
||||
|
||||
xwl_present_flip_try_ready(xwl_present_window);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
|
||||
{
|
||||
/* Crtc unchanged, no offset. */
|
||||
if (crtc == window_priv->crtc)
|
||||
return;
|
||||
|
||||
xwl_present_release_pixmap(event);
|
||||
xorg_list_del(&event->list);
|
||||
free(event);
|
||||
/* No crtc earlier to offset against, just set the crtc. */
|
||||
if (window_priv->crtc == PresentCrtcNeverSet) {
|
||||
window_priv->msc_offset = 0;
|
||||
window_priv->crtc = crtc;
|
||||
return;
|
||||
}
|
||||
|
||||
/* In window-mode the last correct msc-offset is always kept
|
||||
* in window-priv struct because msc is saved per window and
|
||||
* not per crtc as in screen-mode.
|
||||
*/
|
||||
window_priv->msc_offset += new_msc - window_priv->msc;
|
||||
window_priv->crtc = crtc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xwl_present_cleanup(WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
struct xwl_present_event *event, *tmp;
|
||||
|
||||
if (!xwl_present_window)
|
||||
|
@ -156,12 +342,7 @@ xwl_present_cleanup(WindowPtr window)
|
|||
}
|
||||
|
||||
/* Clear remaining events */
|
||||
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->wait_list, list)
|
||||
xwl_present_free_event(event);
|
||||
|
||||
xwl_present_free_event(xwl_present_window->sync_flip);
|
||||
|
||||
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_list, list)
|
||||
xorg_list_for_each_entry_safe(event, tmp, &window_priv->vblank, vblank.window_list)
|
||||
xwl_present_free_event(event);
|
||||
|
||||
/* Clear timer */
|
||||
|
@ -178,53 +359,42 @@ xwl_present_cleanup(WindowPtr window)
|
|||
static void
|
||||
xwl_present_buffer_release(void *data)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window;
|
||||
struct xwl_present_event *event = data;
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
xwl_present_release_pixmap(event);
|
||||
vblank = &event->vblank;
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
|
||||
if (!event->abort)
|
||||
present_wnmd_idle_notify(event->xwl_present_window->window, event->event_id);
|
||||
|
||||
if (!event->pending)
|
||||
xwl_present_window = xwl_present_window_priv(vblank->window);
|
||||
if (xwl_present_window->flip_active == vblank ||
|
||||
xwl_present_get_pending_flip(xwl_present_window) == vblank)
|
||||
xwl_present_release_pixmap(event);
|
||||
else
|
||||
xwl_present_free_event(event);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
|
||||
{
|
||||
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
uint64_t msc = ++xwl_present_window->msc;
|
||||
struct xwl_present_event *event, *tmp;
|
||||
present_vblank_ptr vblank, tmp;
|
||||
|
||||
xwl_present_window->ust = GetTimeInMicros();
|
||||
|
||||
event = xwl_present_window->sync_flip;
|
||||
xwl_present_window->sync_flip = NULL;
|
||||
if (event) {
|
||||
event->pending = FALSE;
|
||||
if (flip_pending && flip_pending->sync_flip)
|
||||
xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
|
||||
|
||||
present_wnmd_flip_notify(xwl_present_window->window, event->event_id,
|
||||
xwl_present_window->ust, msc);
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->wait_list, event_queue) {
|
||||
if (vblank->exec_msc <= msc) {
|
||||
DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
|
||||
vblank->event_id, xwl_present_window->ust, msc));
|
||||
|
||||
if (!event->pixmap) {
|
||||
/* If the buffer was already released, clean up now */
|
||||
xwl_present_free_event(event);
|
||||
} else {
|
||||
xorg_list_add(&event->list, &xwl_present_window->release_list);
|
||||
}
|
||||
}
|
||||
|
||||
xorg_list_for_each_entry_safe(event, tmp,
|
||||
&xwl_present_window->wait_list,
|
||||
list) {
|
||||
if (event->target_msc <= msc) {
|
||||
present_wnmd_event_notify(xwl_present_window->window,
|
||||
event->event_id,
|
||||
xwl_present_window->ust,
|
||||
msc);
|
||||
xwl_present_free_event(event);
|
||||
xwl_present_execute(vblank, xwl_present_window->ust, msc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,20 +435,13 @@ xwl_present_sync_callback(void *data,
|
|||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
struct xwl_present_event *event = data;
|
||||
struct xwl_present_window *xwl_present_window = event->xwl_present_window;
|
||||
present_vblank_ptr vblank = data;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(vblank->window);
|
||||
|
||||
wl_callback_destroy(xwl_present_window->sync_callback);
|
||||
xwl_present_window->sync_callback = NULL;
|
||||
|
||||
event->pending = FALSE;
|
||||
|
||||
if (!event->abort)
|
||||
present_wnmd_flip_notify(xwl_present_window->window, event->event_id,
|
||||
xwl_present_window->ust, xwl_present_window->msc);
|
||||
|
||||
if (!event->pixmap)
|
||||
xwl_present_free_event(event);
|
||||
xwl_present_flip_notify_vblank(vblank, xwl_present_window->ust, xwl_present_window->msc);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener xwl_present_sync_listener = {
|
||||
|
@ -286,7 +449,8 @@ static const struct wl_callback_listener xwl_present_sync_listener = {
|
|||
};
|
||||
|
||||
static RRCrtcPtr
|
||||
xwl_present_get_crtc(WindowPtr present_window)
|
||||
xwl_present_get_crtc(present_screen_priv_ptr screen_priv,
|
||||
WindowPtr present_window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
rrScrPrivPtr rr_private;
|
||||
|
@ -302,43 +466,25 @@ xwl_present_get_crtc(WindowPtr present_window)
|
|||
return rr_private->crtcs[0];
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_present_get_ust_msc(WindowPtr present_window, uint64_t *ust, uint64_t *msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
if (!xwl_present_window)
|
||||
return BadAlloc;
|
||||
|
||||
*ust = xwl_present_window->ust;
|
||||
*msc = xwl_present_window->msc;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue an event to report back to the Present extension when the specified
|
||||
* MSC has past
|
||||
* MSC has passed
|
||||
*/
|
||||
static int
|
||||
xwl_present_queue_vblank(WindowPtr present_window,
|
||||
xwl_present_queue_vblank(ScreenPtr screen,
|
||||
WindowPtr present_window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
|
||||
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
|
||||
struct xwl_present_event *event;
|
||||
struct xwl_present_event *event = xwl_present_event_from_id(event_id);
|
||||
|
||||
event = malloc(sizeof *event);
|
||||
if (!event)
|
||||
return BadAlloc;
|
||||
event->vblank.exec_msc = msc;
|
||||
|
||||
event->event_id = event_id;
|
||||
event->pixmap = NULL;
|
||||
event->xwl_present_window = xwl_present_window;
|
||||
event->target_msc = msc;
|
||||
|
||||
xorg_list_append(&event->list, &xwl_present_window->wait_list);
|
||||
xorg_list_del(&event->vblank.event_queue);
|
||||
xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
|
||||
|
||||
/* If there's a pending frame callback, use that */
|
||||
if (xwl_window && xwl_window->frame_callback &&
|
||||
|
@ -359,30 +505,22 @@ xwl_present_queue_vblank(WindowPtr present_window,
|
|||
* to the extension
|
||||
*/
|
||||
static void
|
||||
xwl_present_abort_vblank(WindowPtr present_window,
|
||||
xwl_present_abort_vblank(ScreenPtr screen,
|
||||
WindowPtr present_window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
|
||||
struct xwl_present_event *event, *tmp;
|
||||
static Bool called;
|
||||
|
||||
if (!xwl_present_window)
|
||||
if (called)
|
||||
return;
|
||||
|
||||
xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->wait_list, list) {
|
||||
if (event->event_id == event_id) {
|
||||
xwl_present_free_event(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xorg_list_for_each_entry(event, &xwl_present_window->release_list, list) {
|
||||
if (event->event_id == event_id) {
|
||||
event->abort = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* xwl_present_cleanup should have cleaned up everything,
|
||||
* present_free_window_vblank shouldn't need to call this.
|
||||
*/
|
||||
ErrorF("Unexpected call to %s:\n", __func__);
|
||||
xorg_backtrace();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -392,18 +530,49 @@ xwl_present_flush(WindowPtr window)
|
|||
}
|
||||
|
||||
static Bool
|
||||
xwl_present_check_flip2(RRCrtcPtr crtc,
|
||||
WindowPtr present_window,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
PresentFlipReason *reason)
|
||||
xwl_present_check_flip(RRCrtcPtr crtc,
|
||||
WindowPtr present_window,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
RegionPtr valid,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
PresentFlipReason *reason)
|
||||
{
|
||||
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
|
||||
struct xwl_window *xwl_window = xwl_window_from_window(present_window);
|
||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||
|
||||
if (reason)
|
||||
*reason = PRESENT_FLIP_REASON_UNKNOWN;
|
||||
|
||||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
||||
if (!crtc)
|
||||
return FALSE;
|
||||
|
||||
/* Source pixmap must align with window exactly */
|
||||
if (x_off || y_off)
|
||||
return FALSE;
|
||||
|
||||
/* Valid area must contain window (for simplicity for now just never flip when one is set). */
|
||||
if (valid)
|
||||
return FALSE;
|
||||
|
||||
/* Flip pixmap must have same dimensions as window */
|
||||
if (present_window->drawable.width != pixmap->drawable.width ||
|
||||
present_window->drawable.height != pixmap->drawable.height)
|
||||
return FALSE;
|
||||
|
||||
/* Window must be same region as toplevel window */
|
||||
if ( !RegionEqual(&present_window->winSize, &toplvl_window->winSize) )
|
||||
return FALSE;
|
||||
|
||||
/* Can't flip if window clipped by children */
|
||||
if (!RegionEqual(&present_window->clipList, &present_window->winSize))
|
||||
return FALSE;
|
||||
|
||||
if (!xwl_glamor_check_flip(pixmap))
|
||||
return FALSE;
|
||||
|
||||
|
@ -425,11 +594,63 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'window' is being reconfigured. Check to see if it is involved
|
||||
* in flipping and clean up as necessary.
|
||||
*/
|
||||
static void
|
||||
xwl_present_check_flip_window (WindowPtr window)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr flip_pending;
|
||||
present_vblank_ptr flip_active;
|
||||
present_vblank_ptr vblank;
|
||||
PresentFlipReason reason;
|
||||
|
||||
/* If this window hasn't ever been used with Present, it can't be
|
||||
* flipping
|
||||
*/
|
||||
if (!xwl_present_window || !window_priv)
|
||||
return;
|
||||
|
||||
flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
flip_active = xwl_present_window->flip_active;
|
||||
|
||||
if (flip_pending) {
|
||||
if (!xwl_present_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
|
||||
flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
|
||||
flip_pending->abort_flip = TRUE;
|
||||
} else if (flip_active) {
|
||||
if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
|
||||
flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
|
||||
xwl_present_flips_stop(window);
|
||||
}
|
||||
|
||||
/* Now check any queued vblanks */
|
||||
xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
|
||||
if (vblank->queued && vblank->flip &&
|
||||
!xwl_present_check_flip(vblank->crtc, window, vblank->pixmap,
|
||||
vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
|
||||
vblank->flip = FALSE;
|
||||
vblank->reason = reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up any pending or current flips for this window
|
||||
*/
|
||||
static void
|
||||
xwl_present_clear_window_flip(WindowPtr window)
|
||||
{
|
||||
/* xwl_present_cleanup cleaned up everything */
|
||||
}
|
||||
|
||||
static Bool
|
||||
xwl_present_flip(WindowPtr present_window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t target_msc,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
RegionPtr damage)
|
||||
|
@ -438,7 +659,7 @@ xwl_present_flip(WindowPtr present_window,
|
|||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
|
||||
BoxPtr damage_box;
|
||||
struct wl_buffer *buffer;
|
||||
struct xwl_present_event *event;
|
||||
struct xwl_present_event *event = xwl_present_event_from_id(event_id);
|
||||
|
||||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
@ -451,30 +672,16 @@ xwl_present_flip(WindowPtr present_window,
|
|||
|
||||
damage_box = RegionExtents(damage);
|
||||
|
||||
event = malloc(sizeof *event);
|
||||
if (!event)
|
||||
return FALSE;
|
||||
|
||||
pixmap->refcnt++;
|
||||
|
||||
event->event_id = event_id;
|
||||
event->xwl_present_window = xwl_present_window;
|
||||
event->pixmap = pixmap;
|
||||
event->target_msc = target_msc;
|
||||
event->pending = TRUE;
|
||||
event->abort = FALSE;
|
||||
|
||||
if (sync_flip) {
|
||||
xorg_list_init(&event->list);
|
||||
xwl_present_window->sync_flip = event;
|
||||
} else {
|
||||
xorg_list_add(&event->list, &xwl_present_window->release_list);
|
||||
}
|
||||
|
||||
xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
|
||||
|
||||
/* We can flip directly to the main surface (full screen window without clips) */
|
||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
||||
wl_surface_set_buffer_scale(xwl_window->surface,
|
||||
xwl_window->xwl_screen->global_output_scale);
|
||||
|
||||
if (!xwl_window->frame_callback)
|
||||
xwl_window_create_frame_callback(xwl_window);
|
||||
|
@ -500,7 +707,7 @@ xwl_present_flip(WindowPtr present_window,
|
|||
wl_display_sync(xwl_window->xwl_screen->display);
|
||||
wl_callback_add_listener(xwl_present_window->sync_callback,
|
||||
&xwl_present_sync_listener,
|
||||
event);
|
||||
&event->vblank);
|
||||
}
|
||||
|
||||
wl_display_flush(xwl_window->xwl_screen->display);
|
||||
|
@ -508,13 +715,206 @@ xwl_present_flip(WindowPtr present_window,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Once the required MSC has been reached, execute the pending request.
|
||||
*
|
||||
* For requests to actually present something, either blt contents to
|
||||
* the window pixmap or queue a window buffer swap on the backend.
|
||||
*
|
||||
* For requests to just get the current MSC/UST combo, skip that part and
|
||||
* go straight to event delivery.
|
||||
*/
|
||||
static void
|
||||
xwl_present_flips_stop(WindowPtr window)
|
||||
xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||
{
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
|
||||
WindowPtr window = vblank->window;
|
||||
struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
|
||||
present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
|
||||
|
||||
/* Change back to the fast refresh rate */
|
||||
xwl_present_reset_timer(xwl_present_window);
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
|
||||
if (present_execute_wait(vblank, crtc_msc))
|
||||
return;
|
||||
|
||||
if (flip_pending && vblank->flip && vblank->pixmap && vblank->window) {
|
||||
DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
|
||||
vblank->event_id, vblank, flip_pending));
|
||||
xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
|
||||
vblank->flip_ready = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
vblank->queued = FALSE;
|
||||
|
||||
if (vblank->pixmap && vblank->window) {
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
|
||||
if (vblank->flip) {
|
||||
RegionPtr damage;
|
||||
|
||||
DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank->event_id, vblank, crtc_msc,
|
||||
vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||
|
||||
/* Set update region as damaged */
|
||||
if (vblank->update) {
|
||||
damage = RegionDuplicate(vblank->update);
|
||||
/* Translate update region to screen space */
|
||||
assert(vblank->x_off == 0 && vblank->y_off == 0);
|
||||
RegionTranslate(damage, window->drawable.x, window->drawable.y);
|
||||
RegionIntersect(damage, damage, &window->clipList);
|
||||
} else
|
||||
damage = RegionDuplicate(&window->clipList);
|
||||
|
||||
if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
|
||||
vblank->pixmap, vblank->sync_flip, damage)) {
|
||||
WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
|
||||
PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
|
||||
|
||||
/* Replace window pixmap with flip pixmap */
|
||||
#ifdef COMPOSITE
|
||||
vblank->pixmap->screen_x = old_pixmap->screen_x;
|
||||
vblank->pixmap->screen_y = old_pixmap->screen_y;
|
||||
#endif
|
||||
present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
|
||||
vblank->pixmap->refcnt++;
|
||||
dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
|
||||
|
||||
/* Report damage */
|
||||
DamageDamageRegion(&vblank->window->drawable, damage);
|
||||
RegionDestroy(damage);
|
||||
|
||||
/* Put pending flip at the flip queue head */
|
||||
xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
|
||||
return;
|
||||
}
|
||||
|
||||
vblank->flip = FALSE;
|
||||
}
|
||||
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||
|
||||
if (flip_pending)
|
||||
flip_pending->abort_flip = TRUE;
|
||||
else if (xwl_present_window->flip_active)
|
||||
xwl_present_flips_stop(window);
|
||||
|
||||
present_execute_copy(vblank, crtc_msc);
|
||||
assert(!vblank->queued);
|
||||
|
||||
if (xwl_present_queue_vblank(screen, window, vblank->crtc,
|
||||
vblank->event_id, crtc_msc + 1)
|
||||
== Success) {
|
||||
/* Clear the pixmap field, so this will fall through to present_execute_post next time */
|
||||
dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
|
||||
vblank->pixmap = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
present_execute_post(vblank, ust, crtc_msc);
|
||||
}
|
||||
|
||||
static int
|
||||
xwl_present_pixmap(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
uint64_t target_window_msc,
|
||||
uint64_t divisor,
|
||||
uint64_t remainder,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies)
|
||||
{
|
||||
uint64_t ust = 0;
|
||||
uint64_t target_msc;
|
||||
uint64_t crtc_msc = 0;
|
||||
int ret;
|
||||
present_vblank_ptr vblank, tmp;
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
struct xwl_present_event *event;
|
||||
|
||||
if (!window_priv)
|
||||
return BadAlloc;
|
||||
|
||||
target_crtc = xwl_present_get_crtc(screen_priv, window);
|
||||
|
||||
ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
|
||||
|
||||
xwl_present_update_window_crtc(window_priv, target_crtc, crtc_msc);
|
||||
|
||||
if (ret == Success) {
|
||||
/* Stash the current MSC away in case we need it later
|
||||
*/
|
||||
window_priv->msc = crtc_msc;
|
||||
}
|
||||
|
||||
target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
|
||||
crtc_msc,
|
||||
divisor,
|
||||
remainder,
|
||||
options);
|
||||
|
||||
/*
|
||||
* Look for a matching presentation already on the list...
|
||||
*/
|
||||
|
||||
if (!update && pixmap) {
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
|
||||
|
||||
if (!vblank->pixmap)
|
||||
continue;
|
||||
|
||||
if (!vblank->queued)
|
||||
continue;
|
||||
|
||||
if (vblank->target_msc != target_msc)
|
||||
continue;
|
||||
|
||||
present_vblank_scrap(vblank);
|
||||
if (vblank->flip_ready)
|
||||
xwl_present_re_execute(vblank);
|
||||
}
|
||||
}
|
||||
|
||||
event = calloc(1, sizeof(*event));
|
||||
if (!event)
|
||||
return BadAlloc;
|
||||
|
||||
vblank = &event->vblank;
|
||||
if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
|
||||
target_crtc, wait_fence, idle_fence, options, XWL_PRESENT_CAPS,
|
||||
notifies, num_notifies, target_msc, crtc_msc)) {
|
||||
present_vblank_destroy(vblank);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
vblank->event_id = (uintptr_t)event;
|
||||
|
||||
/* Xwayland presentations always complete (at least) one frame after they
|
||||
* are executed
|
||||
*/
|
||||
vblank->exec_msc = vblank->target_msc - 1;
|
||||
|
||||
vblank->queued = TRUE;
|
||||
if (crtc_msc < vblank->exec_msc) {
|
||||
if (xwl_present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success)
|
||||
return Success;
|
||||
|
||||
DebugPresent(("present_queue_vblank failed\n"));
|
||||
}
|
||||
|
||||
xwl_present_execute(vblank, ust, crtc_msc);
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -527,32 +927,41 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
|
|||
xwl_present_reset_timer(xwl_present_window);
|
||||
}
|
||||
|
||||
static present_wnmd_info_rec xwl_present_info = {
|
||||
.version = PRESENT_SCREEN_INFO_VERSION,
|
||||
.get_crtc = xwl_present_get_crtc,
|
||||
|
||||
.get_ust_msc = xwl_present_get_ust_msc,
|
||||
.queue_vblank = xwl_present_queue_vblank,
|
||||
.abort_vblank = xwl_present_abort_vblank,
|
||||
|
||||
.flush = xwl_present_flush,
|
||||
|
||||
.capabilities = PresentCapabilityAsync,
|
||||
.check_flip2 = xwl_present_check_flip2,
|
||||
.flip = xwl_present_flip,
|
||||
.flips_stop = xwl_present_flips_stop
|
||||
};
|
||||
|
||||
Bool
|
||||
xwl_present_init(ScreenPtr screen)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
present_screen_priv_ptr screen_priv;
|
||||
|
||||
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
return FALSE;
|
||||
|
||||
if (!present_screen_register_priv_keys())
|
||||
return FALSE;
|
||||
|
||||
if (present_screen_priv(screen))
|
||||
return TRUE;
|
||||
|
||||
screen_priv = present_screen_priv_init(screen);
|
||||
if (!screen_priv)
|
||||
return FALSE;
|
||||
|
||||
if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
|
||||
return FALSE;
|
||||
|
||||
return present_wnmd_screen_init(screen, &xwl_present_info);
|
||||
screen_priv->query_capabilities = xwl_present_query_capabilities;
|
||||
screen_priv->get_crtc = xwl_present_get_crtc;
|
||||
|
||||
screen_priv->check_flip = xwl_present_check_flip;
|
||||
screen_priv->check_flip_window = xwl_present_check_flip_window;
|
||||
screen_priv->clear_window_flip = xwl_present_clear_window_flip;
|
||||
|
||||
screen_priv->present_pixmap = xwl_present_pixmap;
|
||||
screen_priv->queue_vblank = xwl_present_queue_vblank;
|
||||
screen_priv->flush = xwl_present_flush;
|
||||
screen_priv->re_execute = xwl_present_re_execute;
|
||||
|
||||
screen_priv->abort_vblank = xwl_present_abort_vblank;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -29,13 +29,12 @@
|
|||
#include <xwayland-config.h>
|
||||
|
||||
#include <dix.h>
|
||||
#include <present_priv.h>
|
||||
|
||||
#include "xwayland-types.h"
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
struct xwl_present_window {
|
||||
struct xwl_present_event *sync_flip;
|
||||
WindowPtr window;
|
||||
struct xorg_list frame_callback_list;
|
||||
|
||||
uint64_t msc;
|
||||
|
@ -46,20 +45,16 @@ struct xwl_present_window {
|
|||
struct wl_callback *sync_callback;
|
||||
|
||||
struct xorg_list wait_list;
|
||||
struct xorg_list release_list;
|
||||
struct xorg_list flip_queue;
|
||||
struct xorg_list idle_queue;
|
||||
|
||||
present_vblank_ptr flip_active;
|
||||
};
|
||||
|
||||
struct xwl_present_event {
|
||||
uint64_t event_id;
|
||||
uint64_t target_msc;
|
||||
present_vblank_rec vblank;
|
||||
|
||||
Bool abort;
|
||||
Bool pending;
|
||||
|
||||
struct xwl_present_window *xwl_present_window;
|
||||
PixmapPtr pixmap;
|
||||
|
||||
struct xorg_list list;
|
||||
};
|
||||
|
||||
void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "xwayland-pixmap.h"
|
||||
#include "xwayland-present.h"
|
||||
#include "xwayland-shm.h"
|
||||
#include "xwayland-window-buffers.h"
|
||||
|
||||
#ifdef MITSHM
|
||||
#include "shmint.h"
|
||||
|
@ -110,6 +111,12 @@ xwl_screen_has_resolution_change_emulation(struct xwl_screen *xwl_screen)
|
|||
return xwl_screen->rootless && xwl_screen_has_viewport_support(xwl_screen);
|
||||
}
|
||||
|
||||
int
|
||||
xwl_scale_to(struct xwl_screen *xwl_screen, int value)
|
||||
{
|
||||
return value / (double)xwl_screen->global_output_scale + 0.5;
|
||||
}
|
||||
|
||||
/* Return the output @ 0x0, falling back to the first output in the list */
|
||||
struct xwl_output *
|
||||
xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
|
||||
|
@ -127,6 +134,37 @@ xwl_screen_get_first_output(struct xwl_screen *xwl_screen)
|
|||
return xorg_list_first_entry(&xwl_screen->output_list, struct xwl_output, link);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_screen_set_global_scale_from_property(struct xwl_screen *screen,
|
||||
PropertyPtr prop)
|
||||
{
|
||||
CARD32 *propdata;
|
||||
|
||||
if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
|
||||
// TODO: handle warnings more cleanly.
|
||||
LogMessageVerb(X_WARNING, 0, "Bad value for property %s.\n",
|
||||
NameForAtom(prop->propertyName));
|
||||
return;
|
||||
}
|
||||
|
||||
propdata = prop->data;
|
||||
xwl_screen_set_global_scale(screen, propdata[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_screen_update_property(struct xwl_screen *screen,
|
||||
PropertyStateRec *propstate)
|
||||
{
|
||||
switch (propstate->state) {
|
||||
case PropertyNewValue:
|
||||
xwl_screen_set_global_scale_from_property(screen, propstate->prop);
|
||||
break;
|
||||
case PropertyDelete:
|
||||
xwl_screen_set_global_scale(screen, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xwl_property_callback(CallbackListPtr *pcbl, void *closure,
|
||||
void *calldata)
|
||||
|
@ -134,19 +172,24 @@ xwl_property_callback(CallbackListPtr *pcbl, void *closure,
|
|||
ScreenPtr screen = closure;
|
||||
PropertyStateRec *rec = calldata;
|
||||
struct xwl_screen *xwl_screen;
|
||||
struct xwl_window *xwl_window;
|
||||
|
||||
if (rec->win->drawable.pScreen != screen)
|
||||
return;
|
||||
|
||||
xwl_window = xwl_window_get(rec->win);
|
||||
if (!xwl_window)
|
||||
return;
|
||||
|
||||
xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
if (rec->prop->propertyName == xwl_screen->allow_commits_prop)
|
||||
if (rec->prop->propertyName == xwl_screen->allow_commits_prop) {
|
||||
struct xwl_window *xwl_window;
|
||||
|
||||
xwl_window = xwl_window_get(rec->win);
|
||||
if (!xwl_window)
|
||||
return;
|
||||
|
||||
xwl_window_update_property(xwl_window, rec);
|
||||
}
|
||||
else if (rec->prop->propertyName == xwl_screen->global_output_scale_prop) {
|
||||
xwl_screen_update_property(xwl_screen, rec);
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -521,8 +564,14 @@ void xwl_surface_damage(struct xwl_screen *xwl_screen,
|
|||
{
|
||||
if (wl_surface_get_version(surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
|
||||
wl_surface_damage_buffer(surface, x, y, width, height);
|
||||
else
|
||||
else {
|
||||
x = xwl_scale_to(xwl_screen, x);
|
||||
y = xwl_scale_to(xwl_screen, y);
|
||||
width = xwl_scale_to(xwl_screen, width);
|
||||
height = xwl_scale_to(xwl_screen, height);
|
||||
|
||||
wl_surface_damage(surface, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -538,10 +587,34 @@ xwl_screen_roundtrip(struct xwl_screen *xwl_screen)
|
|||
xwl_give_up("could not connect to wayland server\n");
|
||||
}
|
||||
|
||||
void
|
||||
xwl_screen_set_global_scale(struct xwl_screen *xwl_screen, int32_t scale)
|
||||
{
|
||||
struct xwl_output *it;
|
||||
struct xwl_window *xwl_window;
|
||||
|
||||
xwl_screen->global_output_scale = scale;
|
||||
|
||||
/* change randr resolutions and positions */
|
||||
xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
|
||||
xwl_output_apply_changes(it);
|
||||
}
|
||||
|
||||
if (!xwl_screen->rootless && xwl_screen->screen->root) {
|
||||
/* Clear all the buffers, so that they'll be remade with the new sizes
|
||||
* (this doesn't occur automatically because as far as Xorg is
|
||||
* concerned, the window's size is the same) */
|
||||
xorg_list_for_each_entry(xwl_window, &xwl_screen->window_list, link_window) {
|
||||
xwl_window_buffers_recycle(xwl_window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||
{
|
||||
static const char allow_commits[] = "_XWAYLAND_ALLOW_COMMITS";
|
||||
static const char global_output_scale[] = "_XWAYLAND_GLOBAL_OUTPUT_SCALE";
|
||||
struct xwl_screen *xwl_screen;
|
||||
Pixel red_mask, blue_mask, green_mask;
|
||||
int ret, bpc, green_bpc, i;
|
||||
|
@ -573,6 +646,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
|||
#ifdef XWL_HAS_GLAMOR
|
||||
xwl_screen->glamor = 1;
|
||||
#endif
|
||||
xwl_screen->global_output_scale = 1;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-rootless") == 0) {
|
||||
|
@ -743,6 +817,12 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
|||
if (xwl_screen->allow_commits_prop == BAD_RESOURCE)
|
||||
return FALSE;
|
||||
|
||||
xwl_screen->global_output_scale_prop = MakeAtom(global_output_scale,
|
||||
strlen(global_output_scale),
|
||||
TRUE);
|
||||
if (xwl_screen->global_output_scale_prop == BAD_RESOURCE)
|
||||
return FALSE;
|
||||
|
||||
AddCallback(&PropertyStateCallback, xwl_property_callback, pScreen);
|
||||
|
||||
xwl_screen_roundtrip(xwl_screen);
|
||||
|
|
|
@ -72,6 +72,8 @@ struct xwl_screen {
|
|||
struct xorg_list damage_window_list;
|
||||
struct xorg_list window_list;
|
||||
|
||||
int32_t global_output_scale;
|
||||
|
||||
int wayland_fd;
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
|
@ -107,6 +109,7 @@ struct xwl_screen {
|
|||
struct glamor_context *glamor_ctx;
|
||||
|
||||
Atom allow_commits_prop;
|
||||
Atom global_output_scale_prop;
|
||||
|
||||
/* The preferred GLVND vendor. If NULL, "mesa" is assumed. */
|
||||
const char *glvnd_vendor;
|
||||
|
@ -134,5 +137,7 @@ void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
|
|||
void xwl_surface_damage(struct xwl_screen *xwl_screen,
|
||||
struct wl_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
int xwl_scale_to(struct xwl_screen *xwl_screen, int value);
|
||||
void xwl_screen_set_global_scale(struct xwl_screen *xwl_screen, int32_t scale);
|
||||
|
||||
#endif /* XWAYLAND_SCREEN_H */
|
||||
|
|
|
@ -470,7 +470,8 @@ ensure_surface_for_window(WindowPtr window)
|
|||
}
|
||||
|
||||
wl_region_add(region, 0, 0,
|
||||
window->drawable.width, window->drawable.height);
|
||||
xwl_scale_to(xwl_screen, window->drawable.width),
|
||||
xwl_scale_to(xwl_screen, window->drawable.height));
|
||||
wl_surface_set_opaque_region(xwl_window->surface, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
@ -820,6 +821,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
|
|||
#endif
|
||||
|
||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
||||
wl_surface_set_buffer_scale(xwl_window->surface, xwl_screen->global_output_scale);
|
||||
|
||||
/* Arbitrary limit to try to avoid flooding the Wayland
|
||||
* connection. If we flood it too much anyway, this could
|
||||
|
|
104
include/dix.h
104
include/dix.h
|
@ -61,60 +61,76 @@ SOFTWARE.
|
|||
#define LATER 1
|
||||
|
||||
#define NullClient ((ClientPtr) 0)
|
||||
#define REQUEST(type) \
|
||||
type *stuff = (type *)client->requestBuffer
|
||||
|
||||
#define REQUEST(type) \
|
||||
type * stuff = (type *)client->requestBuffer;
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
|
||||
|
||||
#define REQUEST_SIZE_MATCH(req)\
|
||||
if ((sizeof(req) >> 2) != client->req_len)\
|
||||
return(BadLength)
|
||||
#define REQUEST_SIZE_MATCH(req) \
|
||||
do { \
|
||||
if ((sizeof(req) >> 2) != client->req_len) \
|
||||
return(BadLength); \
|
||||
} while (0)
|
||||
|
||||
#define REQUEST_AT_LEAST_SIZE(req) \
|
||||
if ((sizeof(req) >> 2) > client->req_len )\
|
||||
return(BadLength)
|
||||
#define REQUEST_AT_LEAST_SIZE(req) \
|
||||
do { \
|
||||
if ((sizeof(req) >> 2) > client->req_len) \
|
||||
return(BadLength); \
|
||||
} while (0)
|
||||
|
||||
#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \
|
||||
if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \
|
||||
return(BadLength)
|
||||
#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \
|
||||
do { \
|
||||
if (((sizeof(req) + ((uint64_t) (extra))) >> 2) > client->req_len) \
|
||||
return(BadLength); \
|
||||
} while (0)
|
||||
|
||||
#define REQUEST_FIXED_SIZE(req, n)\
|
||||
if (((sizeof(req) >> 2) > client->req_len) || \
|
||||
(((n) >> 2) >= client->req_len) || \
|
||||
((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \
|
||||
return(BadLength)
|
||||
#define REQUEST_FIXED_SIZE(req, n) \
|
||||
do { \
|
||||
if ((((sizeof(req)) >> 2) > client->req_len) || \
|
||||
(((n) >> 2) >= client->req_len) || \
|
||||
((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \
|
||||
return(BadLength); \
|
||||
} while (0)
|
||||
|
||||
#define LEGAL_NEW_RESOURCE(id,client)\
|
||||
if (!LegalNewID(id,client)) \
|
||||
{\
|
||||
client->errorValue = id;\
|
||||
return BadIDChoice;\
|
||||
}
|
||||
#define LEGAL_NEW_RESOURCE(id,client) \
|
||||
do { \
|
||||
if (!LegalNewID((id), (client))) { \
|
||||
(client)->errorValue = (id); \
|
||||
return BadIDChoice; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define VALIDATE_DRAWABLE_AND_GC(drawID, pDraw, mode)\
|
||||
{\
|
||||
int tmprc = dixLookupDrawable(&(pDraw), drawID, client, M_ANY, mode);\
|
||||
if (tmprc != Success)\
|
||||
return tmprc;\
|
||||
tmprc = dixLookupGC(&(pGC), stuff->gc, client, DixUseAccess);\
|
||||
if (tmprc != Success)\
|
||||
return tmprc;\
|
||||
if ((pGC->depth != pDraw->depth) || (pGC->pScreen != pDraw->pScreen))\
|
||||
return BadMatch;\
|
||||
}\
|
||||
if (pGC->serialNumber != pDraw->serialNumber)\
|
||||
ValidateGC(pDraw, pGC);
|
||||
#define VALIDATE_DRAWABLE_AND_GC(drawID, pDraw, mode) \
|
||||
do { \
|
||||
int tmprc = dixLookupDrawable(&(pDraw), drawID, client, M_ANY, mode); \
|
||||
if (tmprc != Success) \
|
||||
return tmprc; \
|
||||
tmprc = dixLookupGC(&(pGC), stuff->gc, client, DixUseAccess); \
|
||||
if (tmprc != Success) \
|
||||
return tmprc; \
|
||||
if ((pGC->depth != pDraw->depth) || (pGC->pScreen != pDraw->pScreen)) \
|
||||
return BadMatch; \
|
||||
if (pGC->serialNumber != pDraw->serialNumber) \
|
||||
ValidateGC(pDraw, pGC); \
|
||||
} while (0)
|
||||
|
||||
#define WriteReplyToClient(pClient, size, pReply) { \
|
||||
if ((pClient)->swapped) \
|
||||
(*ReplySwapVector[((xReq *)(pClient)->requestBuffer)->reqType]) \
|
||||
(pClient, (int)(size), pReply); \
|
||||
else WriteToClient(pClient, (int)(size), (pReply)); }
|
||||
#define WriteReplyToClient(pClient, size, pReply) \
|
||||
do { \
|
||||
if ((pClient)->swapped) \
|
||||
(*ReplySwapVector[((xReq *)(pClient)->requestBuffer)->reqType]) \
|
||||
(pClient, (int)(size), pReply); \
|
||||
else \
|
||||
WriteToClient(pClient, (int)(size), (pReply)); \
|
||||
} while (0)
|
||||
|
||||
#define WriteSwappedDataToClient(pClient, size, pbuf) \
|
||||
if ((pClient)->swapped) \
|
||||
(*(pClient)->pSwapReplyFunc)(pClient, (int)(size), pbuf); \
|
||||
else WriteToClient(pClient, (int)(size), (pbuf));
|
||||
#define WriteSwappedDataToClient(pClient, size, pbuf) \
|
||||
do { \
|
||||
if ((pClient)->swapped) \
|
||||
(*(pClient)->pSwapReplyFunc)(pClient, (int)(size), pbuf); \
|
||||
else \
|
||||
WriteToClient(pClient, (int)(size), (pbuf)); \
|
||||
} while (0)
|
||||
|
||||
typedef struct _TimeStamp *TimeStampPtr;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ extern _X_EXPORT int dixChangeWindowProperty(ClientPtr pClient,
|
|||
int format,
|
||||
int mode,
|
||||
unsigned long len,
|
||||
void *value,
|
||||
const void *value,
|
||||
Bool sendevent);
|
||||
|
||||
extern _X_EXPORT int DeleteProperty(ClientPtr /*client */ ,
|
||||
|
|
|
@ -164,6 +164,9 @@ a list of accepted extension names is printed.
|
|||
.B \-f \fIvolume\fP
|
||||
sets beep (bell) volume (allowable range: 0-100).
|
||||
.TP 8
|
||||
.B \-fakescreenfps \fFps\fP
|
||||
sets fake presenter screen default fps (allowable range: 1-600).
|
||||
.TP 8
|
||||
.B \-fp \fIfontPath\fP
|
||||
sets the search path for fonts. This path is a comma separated list
|
||||
of directories which the X server searches for font databases.
|
||||
|
|
62
meson.build
62
meson.build
|
@ -6,6 +6,8 @@ project('xserver', 'c',
|
|||
version: '21.0.99.1',
|
||||
meson_version: '>= 0.47.0',
|
||||
)
|
||||
release_date = '2021-07-05'
|
||||
|
||||
add_project_arguments('-DHAVE_DIX_CONFIG_H', language: ['c', 'objc'])
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
|
@ -192,6 +194,7 @@ if (host_machine.system() != 'darwin' and
|
|||
endif
|
||||
endif
|
||||
xorgsdkdir = join_paths(get_option('prefix'), get_option('includedir'), 'xorg')
|
||||
libxcvt_dep = dependency('libxcvt', required: build_xorg)
|
||||
|
||||
build_xwayland = false
|
||||
if (host_machine.system() != 'darwin' and
|
||||
|
@ -208,6 +211,7 @@ if (host_machine.system() != 'darwin' and
|
|||
xwayland_dep = [
|
||||
dependency('wayland-client', version: wayland_req, required: xwayland_required),
|
||||
dependency('wayland-protocols', version: wayland_protocols_req, required: xwayland_required),
|
||||
dependency('libxcvt', required: xwayland_required),
|
||||
]
|
||||
|
||||
if build_glamor
|
||||
|
@ -480,7 +484,7 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
libdrm_required = build_dri1 or build_dri2 or build_dri3
|
||||
libdrm_required = (build_dri1 or build_dri2 or build_dri3) and get_option('drm') == true
|
||||
if not libdrm_dep.found() and libdrm_required
|
||||
error('DRI requested, but LIBDRM not found')
|
||||
endif
|
||||
|
@ -687,6 +691,50 @@ manpage_config.set('modulepath', module_dir)
|
|||
manpage_config.set('suid_wrapper_dir', join_paths(get_option('prefix'), 'libexec'))
|
||||
manpage_config.set('default_font_path', default_font_path)
|
||||
|
||||
require_docs = get_option('docs') == 'true'
|
||||
require_devel_docs = get_option('devel-docs') == 'true'
|
||||
require_docs_pdf = (require_docs or require_devel_docs) and get_option('docs-pdf') == 'true'
|
||||
|
||||
sgml_doctools_dep = dependency('xorg-sgml-doctools',
|
||||
required: require_docs or require_devel_docs)
|
||||
xmlto = find_program('xmlto', required: require_docs or require_devel_docs)
|
||||
xsltproc = find_program('xsltproc', required: require_docs or require_devel_docs)
|
||||
fop = find_program('fop', required: require_docs_pdf)
|
||||
|
||||
build_docs = (get_option('docs') != 'false' and
|
||||
sgml_doctools_dep.found() and
|
||||
xmlto.found())
|
||||
|
||||
build_docs_devel = (get_option('devel-docs') != 'false' and
|
||||
sgml_doctools_dep.found() and
|
||||
xmlto.found())
|
||||
|
||||
build_docs_pdf = (get_option('docs-pdf') != 'false' and
|
||||
(build_docs or build_docs_devel) and
|
||||
fop.found())
|
||||
|
||||
if build_docs or build_docs_devel
|
||||
doc_sgml_path = sgml_doctools_dep.get_pkgconfig_variable('sgmlrootdir')
|
||||
doc_stylesheet_srcdir = join_paths(doc_sgml_path, 'X11')
|
||||
|
||||
# once we bump meson dependency to 0.56.0 we can use
|
||||
# meson.project_build_root() instead of meson.build_root()
|
||||
|
||||
# Meson does not and will not support functions so we are copy-pasting
|
||||
# documentation build code around which is unfortunate
|
||||
# See https://mesonbuild.com/FAQ.html#why-doesnt-meson-have-user-defined-functionsmacros
|
||||
|
||||
docs_xmlto_search_flags = [
|
||||
'--searchpath', doc_stylesheet_srcdir,
|
||||
'--searchpath', meson.build_root(),
|
||||
]
|
||||
|
||||
docs_xslt_search_flags = [
|
||||
'--path', doc_stylesheet_srcdir,
|
||||
'--path', meson.build_root(),
|
||||
]
|
||||
endif
|
||||
|
||||
# Include must come first, as it sets up dix-config.h
|
||||
subdir('include')
|
||||
|
||||
|
@ -726,6 +774,7 @@ endif
|
|||
if build_xorg or get_option('xephyr')
|
||||
subdir('exa')
|
||||
endif
|
||||
subdir('doc')
|
||||
|
||||
# Common static libraries of all X servers
|
||||
libxserver = [
|
||||
|
@ -823,3 +872,14 @@ if build_xorg
|
|||
install_data('xorg-server.m4',
|
||||
install_dir: join_paths(get_option('datadir'), 'aclocal'))
|
||||
endif
|
||||
|
||||
if build_docs or build_docs_devel
|
||||
docxmlconfig = configuration_data()
|
||||
docxmlconfig.set('PACKAGE_VERSION', meson.project_version())
|
||||
docxmlconfig.set('RELEASE_DATE', release_date)
|
||||
configure_file(
|
||||
input: 'xserver.ent.in',
|
||||
output: 'xserver.ent',
|
||||
configuration: docxmlconfig
|
||||
)
|
||||
endif
|
||||
|
|
|
@ -113,6 +113,8 @@ option('xf86-input-inputtest', type: 'boolean', value: true,
|
|||
option('dri1', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Build DRI1 extension (default: auto)')
|
||||
option('dri2', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Build DRI2 extension (default: auto)')
|
||||
option('dri3', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto', description: 'Build DRI3 extension (default: auto)')
|
||||
option('drm', type: 'boolean', value: 'true',
|
||||
description: 'Build Xorg with libdrm support')
|
||||
|
||||
option('apple-applications-dir', type: 'string', value: '/Applications/Utilities',
|
||||
description: 'Applications directory')
|
||||
|
@ -129,3 +131,10 @@ option('libunwind', type: 'boolean', value: false,
|
|||
description: 'Use libunwind for backtrace reporting')
|
||||
|
||||
option('xwayland-path', type: 'string', description: 'Directory containing Xwayland executable')
|
||||
|
||||
option('docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||
description: 'Build documentation')
|
||||
option('devel-docs', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||
description: 'Build development documentation')
|
||||
option('docs-pdf', type: 'combo', choices: ['true', 'false', 'auto'], value: 'auto',
|
||||
description: 'Whether to build PDF version of documentation. Setting is ignored if documentation is not built.')
|
||||
|
|
12
os/utils.c
12
os/utils.c
|
@ -112,6 +112,8 @@ __stdcall unsigned long GetTickCount(void);
|
|||
|
||||
#include "miinitext.h"
|
||||
|
||||
#include "present.h"
|
||||
|
||||
Bool noTestExtensions;
|
||||
|
||||
#ifdef COMPOSITE
|
||||
|
@ -534,6 +536,7 @@ UseMsg(void)
|
|||
ErrorF
|
||||
("-deferglyphs [none|all|16] defer loading of [no|all|16-bit] glyphs\n");
|
||||
ErrorF("-f # bell base (0-100)\n");
|
||||
ErrorF("-fakescreenfps # fake screen default fps (1-600)\n");
|
||||
ErrorF("-fp string default font path\n");
|
||||
ErrorF("-help prints message with these options\n");
|
||||
ErrorF("+iglx Allow creating indirect GLX contexts\n");
|
||||
|
@ -781,6 +784,15 @@ ProcessCommandLine(int argc, char *argv[])
|
|||
else
|
||||
UseMsg();
|
||||
}
|
||||
else if (strcmp(argv[i], "-fakescreenfps") == 0) {
|
||||
if (++i < argc) {
|
||||
FakeScreenFps = (uint32_t) atoi(argv[i]);
|
||||
if (FakeScreenFps < 1 || FakeScreenFps > 600)
|
||||
FatalError("fakescreenfps must be an integer in [1;600] range\n");
|
||||
}
|
||||
else
|
||||
UseMsg();
|
||||
}
|
||||
else if (strcmp(argv[i], "-fp") == 0) {
|
||||
if (++i < argc) {
|
||||
defaultFontPath = argv[i];
|
||||
|
|
|
@ -14,7 +14,6 @@ libpresent_la_SOURCES = \
|
|||
present_request.c \
|
||||
present_scmd.c \
|
||||
present_screen.c \
|
||||
present_vblank.c \
|
||||
present_wnmd.c
|
||||
present_vblank.c
|
||||
|
||||
sdk_HEADERS = present.h presentext.h
|
||||
|
|
|
@ -9,7 +9,6 @@ srcs_present = [
|
|||
'present_scmd.c',
|
||||
'present_screen.c',
|
||||
'present_vblank.c',
|
||||
'present_wnmd.c',
|
||||
]
|
||||
|
||||
hdrs_present = [
|
||||
|
|
|
@ -44,11 +44,19 @@ present_get_crtc(WindowPtr window)
|
|||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
RRCrtcPtr crtc = NULL;
|
||||
|
||||
if (!screen_priv)
|
||||
return NULL;
|
||||
|
||||
return screen_priv->get_crtc(screen_priv, window);
|
||||
crtc = screen_priv->get_crtc(screen_priv, window);
|
||||
if (crtc && !present_screen_priv(crtc->pScreen)) {
|
||||
crtc = RRFirstEnabledCrtc(screen);
|
||||
}
|
||||
if (crtc && !present_screen_priv(crtc->pScreen)) {
|
||||
crtc = NULL;
|
||||
}
|
||||
return crtc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -139,21 +139,6 @@ typedef struct present_screen_info {
|
|||
|
||||
} present_screen_info_rec, *present_screen_info_ptr;
|
||||
|
||||
typedef struct present_wnmd_info {
|
||||
uint32_t version;
|
||||
|
||||
present_get_crtc_ptr get_crtc;
|
||||
present_wnmd_get_ust_msc_ptr get_ust_msc;
|
||||
present_wnmd_queue_vblank_ptr queue_vblank;
|
||||
present_wnmd_abort_vblank_ptr abort_vblank;
|
||||
present_flush_ptr flush;
|
||||
uint32_t capabilities;
|
||||
present_check_flip2_ptr check_flip2;
|
||||
present_wnmd_flip_ptr flip;
|
||||
present_wnmd_flips_stop_ptr flips_stop;
|
||||
|
||||
} present_wnmd_info_rec, *present_wnmd_info_ptr;
|
||||
|
||||
/*
|
||||
* Called when 'event_id' occurs. 'ust' and 'msc' indicate when the
|
||||
* event actually happened
|
||||
|
@ -161,30 +146,8 @@ typedef struct present_wnmd_info {
|
|||
extern _X_EXPORT void
|
||||
present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc);
|
||||
|
||||
/*
|
||||
* Called when 'event_id' occurs for 'window'.
|
||||
* 'ust' and 'msc' indicate when the event actually happened
|
||||
*/
|
||||
extern _X_EXPORT void
|
||||
present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc);
|
||||
|
||||
/*
|
||||
* Called when presentation 'event_id' occurs for 'window'.
|
||||
* 'ust' and 'msc' indicate when the presentation actually happened.
|
||||
*/
|
||||
extern _X_EXPORT void
|
||||
present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc);
|
||||
|
||||
/*
|
||||
* Called when the flipped Pixmap associated with 'event_id' is not used anymore by the DDX.
|
||||
*/
|
||||
extern _X_EXPORT void
|
||||
present_wnmd_idle_notify(WindowPtr window, uint64_t event_id);
|
||||
|
||||
extern _X_EXPORT Bool
|
||||
present_screen_init(ScreenPtr screen, present_screen_info_ptr info);
|
||||
extern _X_EXPORT Bool
|
||||
present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info);
|
||||
|
||||
typedef void (*present_complete_notify_proc)(WindowPtr window,
|
||||
CARD8 kind,
|
||||
|
@ -199,4 +162,6 @@ present_register_complete_notify(present_complete_notify_proc proc);
|
|||
extern _X_EXPORT Bool
|
||||
present_can_window_flip(WindowPtr window);
|
||||
|
||||
extern _X_EXPORT uint32_t FakeScreenFps;
|
||||
|
||||
#endif /* _PRESENT_H_ */
|
||||
|
|
|
@ -113,21 +113,29 @@ present_fake_queue_vblank(ScreenPtr screen,
|
|||
return Success;
|
||||
}
|
||||
|
||||
uint32_t FakeScreenFps = 0;
|
||||
|
||||
void
|
||||
present_fake_screen_init(ScreenPtr screen)
|
||||
{
|
||||
uint32_t fake_fps;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
|
||||
/* For screens with hardware vblank support, the fake code
|
||||
* will be used for off-screen windows and while screens are blanked,
|
||||
* in which case we want a slow interval here
|
||||
*
|
||||
* Otherwise, pretend that the screen runs at 60Hz
|
||||
*/
|
||||
if (screen_priv->info && screen_priv->info->get_crtc)
|
||||
screen_priv->fake_interval = 1000000;
|
||||
else
|
||||
screen_priv->fake_interval = 16667;
|
||||
if (FakeScreenFps)
|
||||
fake_fps = FakeScreenFps;
|
||||
else {
|
||||
/* For screens with hardware vblank support, the fake code
|
||||
* will be used for off-screen windows and while screens are blanked,
|
||||
* in which case we want a large interval here: 1Hz
|
||||
*
|
||||
* Otherwise, pretend that the screen runs at 60Hz
|
||||
*/
|
||||
if (screen_priv->info && screen_priv->info->get_crtc)
|
||||
fake_fps = 1;
|
||||
else
|
||||
fake_fps = 60;
|
||||
}
|
||||
screen_priv->fake_interval = 1000000 / fake_fps;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -81,7 +81,6 @@ struct present_vblank {
|
|||
Bool queued; /* on present_exec_queue */
|
||||
Bool flip; /* planning on using flip */
|
||||
Bool flip_ready; /* wants to flip, but waiting for previous flip or unflip */
|
||||
Bool flip_idler; /* driver explicitly permitted idling */
|
||||
Bool sync_flip; /* do flip synchronous to vblank */
|
||||
Bool abort_flip; /* aborting this flip */
|
||||
PresentFlipReason reason; /* reason for which flip is not possible */
|
||||
|
@ -108,6 +107,7 @@ typedef Bool (*present_priv_check_flip_ptr)(RRCrtcPtr crtc,
|
|||
PresentFlipReason *reason);
|
||||
typedef void (*present_priv_check_flip_window_ptr)(WindowPtr window);
|
||||
typedef Bool (*present_priv_can_window_flip_ptr)(WindowPtr window);
|
||||
typedef void (*present_priv_clear_window_flip_ptr)(WindowPtr window);
|
||||
|
||||
typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
|
@ -126,9 +126,6 @@ typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
|
|||
present_notify_ptr notifies,
|
||||
int num_notifies);
|
||||
|
||||
typedef void (*present_priv_create_event_id_ptr)(present_window_priv_ptr window_priv,
|
||||
present_vblank_ptr vblank);
|
||||
|
||||
typedef int (*present_priv_queue_vblank_ptr)(ScreenPtr screen,
|
||||
WindowPtr window,
|
||||
RRCrtcPtr crtc,
|
||||
|
@ -164,7 +161,6 @@ struct present_screen_priv {
|
|||
Bool flip_sync;
|
||||
|
||||
present_screen_info_ptr info;
|
||||
present_wnmd_info_ptr wnmd_info;
|
||||
|
||||
/* Mode hooks */
|
||||
present_priv_query_capabilities_ptr query_capabilities;
|
||||
|
@ -173,9 +169,9 @@ struct present_screen_priv {
|
|||
present_priv_check_flip_ptr check_flip;
|
||||
present_priv_check_flip_window_ptr check_flip_window;
|
||||
present_priv_can_window_flip_ptr can_window_flip;
|
||||
present_priv_clear_window_flip_ptr clear_window_flip;
|
||||
|
||||
present_priv_pixmap_ptr present_pixmap;
|
||||
present_priv_create_event_id_ptr create_event_id;
|
||||
|
||||
present_priv_queue_vblank_ptr queue_vblank;
|
||||
present_priv_flush_ptr flush;
|
||||
|
@ -221,15 +217,6 @@ struct present_window_priv {
|
|||
uint64_t msc; /* Last reported MSC from the current crtc */
|
||||
struct xorg_list vblank;
|
||||
struct xorg_list notifies;
|
||||
|
||||
/* Used for window flips */
|
||||
uint64_t event_id;
|
||||
struct xorg_list exec_queue;
|
||||
struct xorg_list flip_queue;
|
||||
struct xorg_list idle_queue;
|
||||
|
||||
present_vblank_ptr flip_pending;
|
||||
present_vblank_ptr flip_active;
|
||||
};
|
||||
|
||||
#define PresentCrtcNeverSet ((RRCrtcPtr) 1)
|
||||
|
@ -448,6 +435,11 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv);
|
|||
/*
|
||||
* present_screen.c
|
||||
*/
|
||||
Bool
|
||||
present_screen_register_priv_keys(void);
|
||||
|
||||
present_screen_priv_ptr
|
||||
present_screen_priv_init(ScreenPtr screen);
|
||||
|
||||
/*
|
||||
* present_vblank.c
|
||||
|
@ -455,6 +447,25 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv);
|
|||
void
|
||||
present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc);
|
||||
|
||||
Bool
|
||||
present_vblank_init(present_vblank_ptr vblank,
|
||||
WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
const uint32_t capabilities,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies,
|
||||
uint64_t target_msc,
|
||||
uint64_t crtc_msc);
|
||||
|
||||
present_vblank_ptr
|
||||
present_vblank_create(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
|
@ -467,7 +478,7 @@ present_vblank_create(WindowPtr window,
|
|||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
const uint32_t *capabilities,
|
||||
const uint32_t capabilities,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies,
|
||||
uint64_t target_msc,
|
||||
|
@ -479,10 +490,4 @@ present_vblank_scrap(present_vblank_ptr vblank);
|
|||
void
|
||||
present_vblank_destroy(present_vblank_ptr vblank);
|
||||
|
||||
/*
|
||||
* present_wnmd.c
|
||||
*/
|
||||
void
|
||||
present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv);
|
||||
|
||||
#endif /* _PRESENT_PRIV_H_ */
|
||||
|
|
|
@ -35,20 +35,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
static uint64_t present_event_id;
|
||||
static uint64_t present_scmd_event_id;
|
||||
|
||||
static struct xorg_list present_exec_queue;
|
||||
static struct xorg_list present_flip_queue;
|
||||
|
||||
static void
|
||||
present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
|
||||
|
||||
static void
|
||||
present_scmd_create_event_id(present_window_priv_ptr window_priv,
|
||||
present_vblank_ptr vblank)
|
||||
{
|
||||
vblank->event_id = ++present_event_id;
|
||||
}
|
||||
|
||||
static inline PixmapPtr
|
||||
present_flip_pending_pixmap(ScreenPtr screen)
|
||||
{
|
||||
|
@ -326,7 +320,7 @@ present_unflip(ScreenPtr screen)
|
|||
|
||||
present_restore_screen_pixmap(screen);
|
||||
|
||||
screen_priv->unflip_event_id = ++present_event_id;
|
||||
screen_priv->unflip_event_id = ++present_scmd_event_id;
|
||||
DebugPresent(("u %" PRIu64 "\n", screen_priv->unflip_event_id));
|
||||
(*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);
|
||||
}
|
||||
|
@ -501,6 +495,26 @@ present_scmd_can_window_flip(WindowPtr window)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up any pending or current flips for this window
|
||||
*/
|
||||
static void
|
||||
present_scmd_clear_window_flip(WindowPtr window)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
present_vblank_ptr flip_pending = screen_priv->flip_pending;
|
||||
|
||||
if (flip_pending && flip_pending->window == window) {
|
||||
present_set_abort_flip(screen);
|
||||
flip_pending->window = NULL;
|
||||
}
|
||||
if (screen_priv->flip_window == window) {
|
||||
present_restore_screen_pixmap(screen);
|
||||
screen_priv->flip_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Once the required MSC has been reached, execute the pending request.
|
||||
*
|
||||
|
@ -736,7 +750,7 @@ present_scmd_pixmap(WindowPtr window,
|
|||
wait_fence,
|
||||
idle_fence,
|
||||
options,
|
||||
screen_priv->info ? &screen_priv->info->capabilities : NULL,
|
||||
screen_priv->info ? screen_priv->info->capabilities : 0,
|
||||
notifies,
|
||||
num_notifies,
|
||||
target_msc,
|
||||
|
@ -745,6 +759,8 @@ present_scmd_pixmap(WindowPtr window,
|
|||
if (!vblank)
|
||||
return BadAlloc;
|
||||
|
||||
vblank->event_id = ++present_scmd_event_id;
|
||||
|
||||
if (vblank->flip && vblank->sync_flip)
|
||||
vblank->exec_msc--;
|
||||
|
||||
|
@ -816,9 +832,9 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
|
|||
screen_priv->check_flip = &present_check_flip;
|
||||
screen_priv->check_flip_window = &present_check_flip_window;
|
||||
screen_priv->can_window_flip = &present_scmd_can_window_flip;
|
||||
screen_priv->clear_window_flip = &present_scmd_clear_window_flip;
|
||||
|
||||
screen_priv->present_pixmap = &present_scmd_pixmap;
|
||||
screen_priv->create_event_id = &present_scmd_create_event_id;
|
||||
|
||||
screen_priv->queue_vblank = &present_queue_vblank;
|
||||
screen_priv->flush = &present_flush;
|
||||
|
|
|
@ -42,10 +42,6 @@ present_get_window_priv(WindowPtr window, Bool create)
|
|||
xorg_list_init(&window_priv->vblank);
|
||||
xorg_list_init(&window_priv->notifies);
|
||||
|
||||
xorg_list_init(&window_priv->exec_queue);
|
||||
xorg_list_init(&window_priv->flip_queue);
|
||||
xorg_list_init(&window_priv->idle_queue);
|
||||
|
||||
window_priv->window = window;
|
||||
window_priv->crtc = PresentCrtcNeverSet;
|
||||
dixSetPrivate(&window->devPrivates, &present_window_private_key, window_priv);
|
||||
|
@ -86,50 +82,6 @@ present_free_window_vblank(WindowPtr window)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up any pending or current flips for this window
|
||||
*/
|
||||
static void
|
||||
present_clear_window_flip(WindowPtr window)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
present_vblank_ptr flip_pending = screen_priv->flip_pending;
|
||||
|
||||
if (flip_pending && flip_pending->window == window) {
|
||||
present_set_abort_flip(screen);
|
||||
flip_pending->window = NULL;
|
||||
}
|
||||
if (screen_priv->flip_window == window) {
|
||||
present_restore_screen_pixmap(screen);
|
||||
screen_priv->flip_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_clear_window_flip(WindowPtr window)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank, tmp;
|
||||
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
present_vblank_destroy(vblank);
|
||||
}
|
||||
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
present_vblank_destroy(vblank);
|
||||
}
|
||||
|
||||
vblank = window_priv->flip_active;
|
||||
if (vblank) {
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
present_vblank_destroy(vblank);
|
||||
}
|
||||
window_priv->flip_active = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook the close window function to clean up our window private
|
||||
*/
|
||||
|
@ -146,10 +98,7 @@ present_destroy_window(WindowPtr window)
|
|||
present_free_events(window);
|
||||
present_free_window_vblank(window);
|
||||
|
||||
if (screen_priv->wnmd_info)
|
||||
present_wnmd_clear_window_flip(window);
|
||||
else
|
||||
present_clear_window_flip(window);
|
||||
screen_priv->clear_window_flip(window);
|
||||
|
||||
free(window_priv);
|
||||
}
|
||||
|
@ -202,7 +151,7 @@ present_clip_notify(WindowPtr window, int dx, int dy)
|
|||
wrap(screen_priv, screen, ClipNotify, present_clip_notify);
|
||||
}
|
||||
|
||||
static Bool
|
||||
Bool
|
||||
present_screen_register_priv_keys(void)
|
||||
{
|
||||
if (!dixRegisterPrivateKey(&present_screen_private_key, PRIVATE_SCREEN, 0))
|
||||
|
@ -214,7 +163,7 @@ present_screen_register_priv_keys(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static present_screen_priv_ptr
|
||||
present_screen_priv_ptr
|
||||
present_screen_priv_init(ScreenPtr screen)
|
||||
{
|
||||
present_screen_priv_ptr screen_priv;
|
||||
|
@ -233,27 +182,6 @@ present_screen_priv_init(ScreenPtr screen)
|
|||
return screen_priv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a screen for use with present in window flip mode (wnmd)
|
||||
*/
|
||||
int
|
||||
present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
|
||||
{
|
||||
if (!present_screen_register_priv_keys())
|
||||
return FALSE;
|
||||
|
||||
if (!present_screen_priv(screen)) {
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv_init(screen);
|
||||
if (!screen_priv)
|
||||
return FALSE;
|
||||
|
||||
screen_priv->wnmd_info = info;
|
||||
present_wnmd_init_mode_hooks(screen_priv);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a screen for use with present in default screen flip mode (scmd)
|
||||
*/
|
||||
|
|
|
@ -38,38 +38,39 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
|
|||
}
|
||||
}
|
||||
|
||||
present_vblank_ptr
|
||||
present_vblank_create(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
const uint32_t *capabilities,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies,
|
||||
uint64_t target_msc,
|
||||
uint64_t crtc_msc)
|
||||
/* The memory vblank points to must be 0-initialized before calling this function.
|
||||
*
|
||||
* If this function returns FALSE, present_vblank_destroy must be called to clean
|
||||
* up.
|
||||
*/
|
||||
Bool
|
||||
present_vblank_init(present_vblank_ptr vblank,
|
||||
WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
const uint32_t capabilities,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies,
|
||||
uint64_t target_msc,
|
||||
uint64_t crtc_msc)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
present_vblank_ptr vblank;
|
||||
PresentFlipReason reason = PRESENT_FLIP_REASON_UNKNOWN;
|
||||
|
||||
if (target_crtc) {
|
||||
screen_priv = present_screen_priv(target_crtc->pScreen);
|
||||
}
|
||||
|
||||
vblank = calloc (1, sizeof (present_vblank_rec));
|
||||
if (!vblank)
|
||||
return NULL;
|
||||
|
||||
xorg_list_append(&vblank->window_list, &window_priv->vblank);
|
||||
xorg_list_init(&vblank->event_queue);
|
||||
|
||||
|
@ -77,8 +78,6 @@ present_vblank_create(WindowPtr window,
|
|||
vblank->window = window;
|
||||
vblank->pixmap = pixmap;
|
||||
|
||||
screen_priv->create_event_id(window_priv, vblank);
|
||||
|
||||
if (pixmap) {
|
||||
vblank->kind = PresentCompleteKindPixmap;
|
||||
pixmap->refcnt++;
|
||||
|
@ -107,17 +106,16 @@ present_vblank_create(WindowPtr window,
|
|||
vblank->notifies = notifies;
|
||||
vblank->num_notifies = num_notifies;
|
||||
vblank->has_suboptimal = (options & PresentOptionSuboptimal);
|
||||
vblank->flip_idler = FALSE;
|
||||
|
||||
if (pixmap != NULL &&
|
||||
!(options & PresentOptionCopy) &&
|
||||
capabilities) {
|
||||
screen_priv->check_flip) {
|
||||
if (msc_is_after(target_msc, crtc_msc) &&
|
||||
screen_priv->check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off, &reason))
|
||||
{
|
||||
vblank->flip = TRUE;
|
||||
vblank->sync_flip = TRUE;
|
||||
} else if ((*capabilities & PresentCapabilityAsync) &&
|
||||
} else if ((capabilities & PresentCapabilityAsync) &&
|
||||
screen_priv->check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off, &reason))
|
||||
{
|
||||
vblank->flip = TRUE;
|
||||
|
@ -142,10 +140,42 @@ present_vblank_create(WindowPtr window,
|
|||
vblank->event_id, vblank, target_msc,
|
||||
vblank->pixmap->drawable.id, vblank->window->drawable.id,
|
||||
target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
|
||||
return vblank;
|
||||
return TRUE;
|
||||
|
||||
no_mem:
|
||||
vblank->notifies = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
present_vblank_ptr
|
||||
present_vblank_create(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
const uint32_t capabilities,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies,
|
||||
uint64_t target_msc,
|
||||
uint64_t crtc_msc)
|
||||
{
|
||||
present_vblank_ptr vblank = calloc(1, sizeof(present_vblank_rec));
|
||||
|
||||
if (!vblank)
|
||||
return NULL;
|
||||
|
||||
if (present_vblank_init(vblank, window, pixmap, serial, valid, update,
|
||||
x_off, y_off, target_crtc, wait_fence, idle_fence,
|
||||
options, capabilities, notifies, num_notifies,
|
||||
target_msc, crtc_msc))
|
||||
return vblank;
|
||||
|
||||
present_vblank_destroy(vblank);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,702 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Roman Gilg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "present_priv.h"
|
||||
|
||||
/*
|
||||
* Window flip mode
|
||||
*
|
||||
* Provides per-window flips. Flips can be processed on windows that
|
||||
* have the same size as their parents, which they share their pixmap with.
|
||||
*
|
||||
* A flip still requires a copy currently, since the original pixmap needs
|
||||
* to be updated with the new pixmap content. Just a flip of all windows
|
||||
* to the new pixmap is difficult, because the original pixmap might not be
|
||||
* controlled by the Xserver.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
|
||||
|
||||
static int
|
||||
present_wnmd_queue_vblank(ScreenPtr screen,
|
||||
WindowPtr window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t msc)
|
||||
{
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
return (*screen_priv->wnmd_info->queue_vblank) (window, crtc, event_id, msc);
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_create_event_id(present_window_priv_ptr window_priv, present_vblank_ptr vblank)
|
||||
{
|
||||
vblank->event_id = ++window_priv->event_id;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
present_wnmd_query_capabilities(present_screen_priv_ptr screen_priv)
|
||||
{
|
||||
return screen_priv->wnmd_info->capabilities;
|
||||
}
|
||||
|
||||
static RRCrtcPtr
|
||||
present_wnmd_get_crtc(present_screen_priv_ptr screen_priv, WindowPtr window)
|
||||
{
|
||||
return (*screen_priv->wnmd_info->get_crtc)(window);
|
||||
}
|
||||
|
||||
static int
|
||||
present_wnmd_get_ust_msc(ScreenPtr screen, WindowPtr window, uint64_t *ust, uint64_t *msc)
|
||||
{
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
return (*screen_priv->wnmd_info->get_ust_msc)(window, ust, msc);
|
||||
}
|
||||
|
||||
/*
|
||||
* When the wait fence or previous flip is completed, it's time
|
||||
* to re-try the request
|
||||
*/
|
||||
static void
|
||||
present_wnmd_re_execute(present_vblank_ptr vblank)
|
||||
{
|
||||
uint64_t ust = 0, crtc_msc = 0;
|
||||
|
||||
(void) present_wnmd_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
|
||||
present_wnmd_execute(vblank, ust, crtc_msc);
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_flip_try_ready(WindowPtr window)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
|
||||
if (vblank->queued) {
|
||||
present_wnmd_re_execute(vblank);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_free_idle_vblank(present_vblank_ptr vblank)
|
||||
{
|
||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||
present_vblank_destroy(vblank);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free any left over idle vblanks
|
||||
*/
|
||||
static void
|
||||
present_wnmd_free_idle_vblanks(WindowPtr window)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank, tmp;
|
||||
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
|
||||
present_wnmd_free_idle_vblank(vblank);
|
||||
}
|
||||
|
||||
if (window_priv->flip_active) {
|
||||
present_wnmd_free_idle_vblank(window_priv->flip_active);
|
||||
window_priv->flip_active = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static WindowPtr
|
||||
present_wnmd_toplvl_pixmap_window(WindowPtr window)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
PixmapPtr pixmap = (*screen->GetWindowPixmap)(window);
|
||||
WindowPtr w = window;
|
||||
WindowPtr next_w;
|
||||
|
||||
while(w->parent) {
|
||||
next_w = w->parent;
|
||||
if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
|
||||
break;
|
||||
}
|
||||
w = next_w;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_flips_stop(WindowPtr window)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(window->drawable.pScreen);
|
||||
|
||||
assert (!window_priv->flip_pending);
|
||||
|
||||
(*screen_priv->wnmd_info->flips_stop) (window);
|
||||
|
||||
present_wnmd_free_idle_vblanks(window_priv->window);
|
||||
present_wnmd_flip_try_ready(window_priv->window);
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||
{
|
||||
WindowPtr window = vblank->window;
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
|
||||
DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
|
||||
vblank->pixmap ? vblank->pixmap->drawable.id : 0,
|
||||
vblank->window ? vblank->window->drawable.id : 0));
|
||||
|
||||
assert (vblank == window_priv->flip_pending);
|
||||
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
|
||||
if (window_priv->flip_active) {
|
||||
if (window_priv->flip_active->flip_idler)
|
||||
present_wnmd_free_idle_vblank(window_priv->flip_active);
|
||||
else
|
||||
/* Put the previous flip in the idle_queue and wait for further notice from DDX */
|
||||
xorg_list_append(&window_priv->flip_active->event_queue, &window_priv->idle_queue);
|
||||
}
|
||||
|
||||
window_priv->flip_active = vblank;
|
||||
window_priv->flip_pending = NULL;
|
||||
|
||||
present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
|
||||
|
||||
if (vblank->abort_flip)
|
||||
present_wnmd_flips_stop(window);
|
||||
|
||||
present_wnmd_flip_try_ready(window);
|
||||
}
|
||||
|
||||
void
|
||||
present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
if (!window_priv)
|
||||
return;
|
||||
if (!event_id)
|
||||
return;
|
||||
|
||||
DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
|
||||
xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) {
|
||||
if (event_id == vblank->event_id) {
|
||||
present_wnmd_execute(vblank, ust, msc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
assert(vblank->queued);
|
||||
present_wnmd_execute(vblank, ust, msc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copies which were executed but need their completion event sent */
|
||||
xorg_list_for_each_entry(vblank, &window_priv->idle_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
present_execute_post(vblank, ust, msc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
assert(!vblank->queued);
|
||||
assert(vblank->window);
|
||||
present_wnmd_flip_notify_vblank(vblank, ust, msc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
if (window_priv->flip_active && window_priv->flip_active->event_id == event_id) {
|
||||
/* Active flip is allowed to become idle directly when it becomes unactive again. */
|
||||
window_priv->flip_active->flip_idler = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
xorg_list_for_each_entry(vblank, &window_priv->idle_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
present_wnmd_free_idle_vblank(vblank);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
vblank->flip_idler = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
present_wnmd_check_flip(RRCrtcPtr crtc,
|
||||
WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
RegionPtr valid,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
PresentFlipReason *reason)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(window);
|
||||
|
||||
if (reason)
|
||||
*reason = PRESENT_FLIP_REASON_UNKNOWN;
|
||||
|
||||
if (!screen_priv)
|
||||
return FALSE;
|
||||
|
||||
if (!screen_priv->wnmd_info)
|
||||
return FALSE;
|
||||
|
||||
if (!crtc)
|
||||
return FALSE;
|
||||
|
||||
/* Check to see if the driver supports flips at all */
|
||||
if (!screen_priv->wnmd_info->flip)
|
||||
return FALSE;
|
||||
|
||||
/* Source pixmap must align with window exactly */
|
||||
if (x_off || y_off)
|
||||
return FALSE;
|
||||
|
||||
/* Valid area must contain window (for simplicity for now just never flip when one is set). */
|
||||
if (valid)
|
||||
return FALSE;
|
||||
|
||||
/* Flip pixmap must have same dimensions as window */
|
||||
if (window->drawable.width != pixmap->drawable.width ||
|
||||
window->drawable.height != pixmap->drawable.height)
|
||||
return FALSE;
|
||||
|
||||
/* Window must be same region as toplevel window */
|
||||
if ( !RegionEqual(&window->winSize, &toplvl_window->winSize) )
|
||||
return FALSE;
|
||||
|
||||
/* Can't flip if window clipped by children */
|
||||
if (!RegionEqual(&window->clipList, &window->winSize))
|
||||
return FALSE;
|
||||
|
||||
/* Ask the driver for permission */
|
||||
if (screen_priv->wnmd_info->check_flip2) {
|
||||
if (!(*screen_priv->wnmd_info->check_flip2) (crtc, window, pixmap, sync_flip, reason)) {
|
||||
DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
window->drawable.id, pixmap ? pixmap->drawable.id : 0));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 'window' is being reconfigured. Check to see if it is involved
|
||||
* in flipping and clean up as necessary.
|
||||
*/
|
||||
static void
|
||||
present_wnmd_check_flip_window (WindowPtr window)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr flip_pending;
|
||||
present_vblank_ptr flip_active;
|
||||
present_vblank_ptr vblank;
|
||||
PresentFlipReason reason;
|
||||
|
||||
/* If this window hasn't ever been used with Present, it can't be
|
||||
* flipping
|
||||
*/
|
||||
if (!window_priv)
|
||||
return;
|
||||
|
||||
flip_pending = window_priv->flip_pending;
|
||||
flip_active = window_priv->flip_active;
|
||||
|
||||
if (flip_pending) {
|
||||
if (!present_wnmd_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
|
||||
flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
|
||||
window_priv->flip_pending->abort_flip = TRUE;
|
||||
} else if (flip_active) {
|
||||
if (!present_wnmd_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
|
||||
flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
|
||||
present_wnmd_flips_stop(window);
|
||||
}
|
||||
|
||||
/* Now check any queued vblanks */
|
||||
xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
|
||||
if (vblank->queued && vblank->flip &&
|
||||
!present_wnmd_check_flip(vblank->crtc, window, vblank->pixmap,
|
||||
vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
|
||||
vblank->flip = FALSE;
|
||||
vblank->reason = reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
present_wnmd_flip(WindowPtr window,
|
||||
RRCrtcPtr crtc,
|
||||
uint64_t event_id,
|
||||
uint64_t target_msc,
|
||||
PixmapPtr pixmap,
|
||||
Bool sync_flip,
|
||||
RegionPtr damage)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
|
||||
return (*screen_priv->wnmd_info->flip) (window,
|
||||
crtc,
|
||||
event_id,
|
||||
target_msc,
|
||||
pixmap,
|
||||
sync_flip,
|
||||
damage);
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_cancel_flip(WindowPtr window)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
|
||||
if (window_priv->flip_pending)
|
||||
window_priv->flip_pending->abort_flip = TRUE;
|
||||
else if (window_priv->flip_active)
|
||||
present_wnmd_flips_stop(window);
|
||||
}
|
||||
|
||||
/*
|
||||
* Once the required MSC has been reached, execute the pending request.
|
||||
*
|
||||
* For requests to actually present something, either blt contents to
|
||||
* the window pixmap or queue a window buffer swap on the backend.
|
||||
*
|
||||
* For requests to just get the current MSC/UST combo, skip that part and
|
||||
* go straight to event delivery.
|
||||
*/
|
||||
static void
|
||||
present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
|
||||
{
|
||||
WindowPtr window = vblank->window;
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
|
||||
if (present_execute_wait(vblank, crtc_msc))
|
||||
return;
|
||||
|
||||
if (vblank->flip && vblank->pixmap && vblank->window) {
|
||||
if (window_priv->flip_pending) {
|
||||
DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
|
||||
vblank->event_id, vblank,
|
||||
window_priv->flip_pending));
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
xorg_list_append(&vblank->event_queue, &window_priv->flip_queue);
|
||||
vblank->flip_ready = TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
xorg_list_del(&vblank->window_list);
|
||||
vblank->queued = FALSE;
|
||||
|
||||
if (vblank->pixmap && vblank->window) {
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
|
||||
if (vblank->flip) {
|
||||
RegionPtr damage;
|
||||
|
||||
DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank->event_id, vblank, crtc_msc,
|
||||
vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||
|
||||
/* Prepare to flip by placing it in the flip queue
|
||||
*/
|
||||
xorg_list_add(&vblank->event_queue, &window_priv->flip_queue);
|
||||
|
||||
/* Set update region as damaged */
|
||||
if (vblank->update) {
|
||||
damage = RegionDuplicate(vblank->update);
|
||||
/* Translate update region to screen space */
|
||||
assert(vblank->x_off == 0 && vblank->y_off == 0);
|
||||
RegionTranslate(damage, window->drawable.x, window->drawable.y);
|
||||
RegionIntersect(damage, damage, &window->clipList);
|
||||
} else
|
||||
damage = RegionDuplicate(&window->clipList);
|
||||
|
||||
/* Try to flip - the vblank is now pending
|
||||
*/
|
||||
window_priv->flip_pending = vblank;
|
||||
// ask the driver
|
||||
if (present_wnmd_flip(vblank->window, vblank->crtc, vblank->event_id,
|
||||
vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
|
||||
WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
|
||||
PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
|
||||
|
||||
/* Replace window pixmap with flip pixmap */
|
||||
#ifdef COMPOSITE
|
||||
vblank->pixmap->screen_x = old_pixmap->screen_x;
|
||||
vblank->pixmap->screen_y = old_pixmap->screen_y;
|
||||
#endif
|
||||
present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
|
||||
vblank->pixmap->refcnt++;
|
||||
dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
|
||||
|
||||
/* Report damage */
|
||||
DamageDamageRegion(&vblank->window->drawable, damage);
|
||||
RegionDestroy(damage);
|
||||
return;
|
||||
}
|
||||
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
/* Flip failed. Clear the flip_pending field
|
||||
*/
|
||||
window_priv->flip_pending = NULL;
|
||||
vblank->flip = FALSE;
|
||||
}
|
||||
DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
|
||||
vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
|
||||
|
||||
present_wnmd_cancel_flip(window);
|
||||
|
||||
present_execute_copy(vblank, crtc_msc);
|
||||
assert(!vblank->queued);
|
||||
|
||||
if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
|
||||
vblank->event_id, crtc_msc + 1)
|
||||
== Success) {
|
||||
xorg_list_add(&vblank->event_queue, &window_priv->idle_queue);
|
||||
xorg_list_append(&vblank->window_list, &window_priv->vblank);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
present_execute_post(vblank, ust, crtc_msc);
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
|
||||
{
|
||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||
|
||||
/* Crtc unchanged, no offset. */
|
||||
if (crtc == window_priv->crtc)
|
||||
return;
|
||||
|
||||
/* No crtc earlier to offset against, just set the crtc. */
|
||||
if (window_priv->crtc == PresentCrtcNeverSet) {
|
||||
window_priv->msc_offset = 0;
|
||||
window_priv->crtc = crtc;
|
||||
return;
|
||||
}
|
||||
|
||||
/* In window-mode the last correct msc-offset is always kept
|
||||
* in window-priv struct because msc is saved per window and
|
||||
* not per crtc as in screen-mode.
|
||||
*/
|
||||
window_priv->msc_offset += new_msc - window_priv->msc;
|
||||
window_priv->crtc = crtc;
|
||||
}
|
||||
|
||||
static int
|
||||
present_wnmd_pixmap(WindowPtr window,
|
||||
PixmapPtr pixmap,
|
||||
CARD32 serial,
|
||||
RegionPtr valid,
|
||||
RegionPtr update,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
RRCrtcPtr target_crtc,
|
||||
SyncFence *wait_fence,
|
||||
SyncFence *idle_fence,
|
||||
uint32_t options,
|
||||
uint64_t target_window_msc,
|
||||
uint64_t divisor,
|
||||
uint64_t remainder,
|
||||
present_notify_ptr notifies,
|
||||
int num_notifies)
|
||||
{
|
||||
uint64_t ust = 0;
|
||||
uint64_t target_msc;
|
||||
uint64_t crtc_msc = 0;
|
||||
int ret;
|
||||
present_vblank_ptr vblank, tmp;
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
|
||||
if (!window_priv)
|
||||
return BadAlloc;
|
||||
|
||||
target_crtc = present_wnmd_get_crtc(screen_priv, window);
|
||||
|
||||
ret = present_wnmd_get_ust_msc(screen, window, &ust, &crtc_msc);
|
||||
|
||||
present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
|
||||
|
||||
if (ret == Success) {
|
||||
/* Stash the current MSC away in case we need it later
|
||||
*/
|
||||
window_priv->msc = crtc_msc;
|
||||
}
|
||||
|
||||
target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
|
||||
crtc_msc,
|
||||
divisor,
|
||||
remainder,
|
||||
options);
|
||||
|
||||
/*
|
||||
* Look for a matching presentation already on the list...
|
||||
*/
|
||||
|
||||
if (!update && pixmap) {
|
||||
xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
|
||||
|
||||
if (!vblank->pixmap)
|
||||
continue;
|
||||
|
||||
if (!vblank->queued)
|
||||
continue;
|
||||
|
||||
if (vblank->target_msc != target_msc)
|
||||
continue;
|
||||
|
||||
present_vblank_scrap(vblank);
|
||||
if (vblank->flip_ready)
|
||||
present_wnmd_re_execute(vblank);
|
||||
}
|
||||
}
|
||||
|
||||
vblank = present_vblank_create(window,
|
||||
pixmap,
|
||||
serial,
|
||||
valid,
|
||||
update,
|
||||
x_off,
|
||||
y_off,
|
||||
target_crtc,
|
||||
wait_fence,
|
||||
idle_fence,
|
||||
options,
|
||||
&screen_priv->wnmd_info->capabilities,
|
||||
notifies,
|
||||
num_notifies,
|
||||
target_msc,
|
||||
crtc_msc);
|
||||
if (!vblank)
|
||||
return BadAlloc;
|
||||
|
||||
/* WNMD presentations always complete (at least) one frame after they
|
||||
* are executed
|
||||
*/
|
||||
vblank->exec_msc = vblank->target_msc - 1;
|
||||
|
||||
xorg_list_append(&vblank->event_queue, &window_priv->exec_queue);
|
||||
vblank->queued = TRUE;
|
||||
if (crtc_msc < vblank->exec_msc) {
|
||||
if (present_wnmd_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success) {
|
||||
return Success;
|
||||
}
|
||||
DebugPresent(("present_queue_vblank failed\n"));
|
||||
}
|
||||
|
||||
present_wnmd_execute(vblank, ust, crtc_msc);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_abort_vblank(ScreenPtr screen, WindowPtr window, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
|
||||
{
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
present_window_priv_ptr window_priv = present_window_priv(window);
|
||||
present_vblank_ptr vblank;
|
||||
|
||||
(*screen_priv->wnmd_info->abort_vblank) (window, crtc, event_id, msc);
|
||||
|
||||
xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
vblank->queued = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
|
||||
if (vblank->event_id == event_id) {
|
||||
xorg_list_del(&vblank->event_queue);
|
||||
vblank->queued = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
present_wnmd_flush(WindowPtr window)
|
||||
{
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||
|
||||
(*screen_priv->wnmd_info->flush) (window);
|
||||
}
|
||||
|
||||
void
|
||||
present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
|
||||
{
|
||||
screen_priv->query_capabilities = &present_wnmd_query_capabilities;
|
||||
screen_priv->get_crtc = &present_wnmd_get_crtc;
|
||||
|
||||
screen_priv->check_flip = &present_wnmd_check_flip;
|
||||
screen_priv->check_flip_window = &present_wnmd_check_flip_window;
|
||||
|
||||
screen_priv->present_pixmap = &present_wnmd_pixmap;
|
||||
screen_priv->create_event_id = &present_wnmd_create_event_id;
|
||||
screen_priv->queue_vblank = &present_wnmd_queue_vblank;
|
||||
screen_priv->flush = &present_wnmd_flush;
|
||||
screen_priv->re_execute = &present_wnmd_re_execute;
|
||||
|
||||
screen_priv->abort_vblank = &present_wnmd_abort_vblank;
|
||||
}
|
|
@ -615,6 +615,10 @@ RRTellChanged(ScreenPtr pScreen)
|
|||
primarysp = pScrPriv;
|
||||
}
|
||||
|
||||
/* If there's no root window yet, can't send events */
|
||||
if (!primary->root)
|
||||
return;
|
||||
|
||||
xorg_list_for_each_entry(iter, &primary->secondary_list, secondary_head) {
|
||||
pSecondaryScrPriv = rrGetScrPriv(iter);
|
||||
|
||||
|
@ -693,6 +697,33 @@ RRFirstOutput(ScreenPtr pScreen)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
RRCrtcPtr
|
||||
RRFirstEnabledCrtc(ScreenPtr pScreen)
|
||||
{
|
||||
rrScrPriv(pScreen);
|
||||
RROutputPtr output;
|
||||
int i, j;
|
||||
|
||||
if (!pScrPriv)
|
||||
return NULL;
|
||||
|
||||
if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc &&
|
||||
pScrPriv->primaryOutput->pScreen == pScreen)
|
||||
return pScrPriv->primaryOutput->crtc;
|
||||
|
||||
for (i = 0; i < pScrPriv->numCrtcs; i++) {
|
||||
RRCrtcPtr crtc = pScrPriv->crtcs[i];
|
||||
|
||||
for (j = 0; j < pScrPriv->numOutputs; j++) {
|
||||
output = pScrPriv->outputs[j];
|
||||
if (output->crtc == crtc && crtc->mode)
|
||||
return crtc;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CARD16
|
||||
RRVerticalRefresh(xRRModeInfo * mode)
|
||||
{
|
||||
|
|
|
@ -593,6 +593,8 @@ extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen);
|
|||
|
||||
extern _X_EXPORT RROutputPtr RRFirstOutput(ScreenPtr pScreen);
|
||||
|
||||
extern _X_EXPORT RRCrtcPtr RRFirstEnabledCrtc(ScreenPtr pScreen);
|
||||
|
||||
extern _X_EXPORT Bool RROutputSetNonDesktop(RROutputPtr output, Bool non_desktop);
|
||||
|
||||
extern _X_EXPORT CARD16
|
||||
|
|
|
@ -182,7 +182,7 @@ if build_xorg
|
|||
unit = executable('tests',
|
||||
unit_sources,
|
||||
c_args: unit_c_args,
|
||||
dependencies: [pixman_dep, randrproto_dep, inputproto_dep],
|
||||
dependencies: [pixman_dep, randrproto_dep, inputproto_dep, libxcvt_dep],
|
||||
include_directories: unit_includes,
|
||||
link_args: ldwraps,
|
||||
link_with: xorg_link,
|
||||
|
|
|
@ -215,7 +215,11 @@ static _X_COLD int
|
|||
SProcXFixesDispatch(ClientPtr client)
|
||||
{
|
||||
REQUEST(xXFixesReq);
|
||||
if (stuff->xfixesReqType >= XFixesNumberRequests)
|
||||
XFixesClientPtr pXFixesClient = GetXFixesClient(client);
|
||||
|
||||
if (pXFixesClient->major_version >= ARRAY_SIZE(version_requests))
|
||||
return BadRequest;
|
||||
if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
|
||||
return BadRequest;
|
||||
return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
|
||||
}
|
||||
|
|
|
@ -870,6 +870,7 @@ CopyISOLockArgs(XkbDescPtr xkb, XkbAction *action, char *buf, int *sz)
|
|||
XkbISOAction *act;
|
||||
char tbuf[64];
|
||||
|
||||
memset(tbuf, 0, sizeof(tbuf));
|
||||
act = &action->iso;
|
||||
if (act->flags & XkbSA_ISODfltIsGroup) {
|
||||
TryCopyStr(tbuf, "group=", sz);
|
||||
|
|
Loading…
Reference in New Issue