BLI: refactor IndexMask for better performance and memory usage #104629
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Early Initialization
|
||||
|
|
|
@ -528,10 +528,10 @@ set(XR_OPENXR_SDK_HASH a2623ebab3d0b340bc16311b14f02075)
|
|||
set(XR_OPENXR_SDK_HASH_TYPE MD5)
|
||||
set(XR_OPENXR_SDK_FILE OpenXR-SDK-${XR_OPENXR_SDK_VERSION}.tar.gz)
|
||||
|
||||
set(WL_PROTOCOLS_VERSION 1.21)
|
||||
set(WL_PROTOCOLS_VERSION 1.31)
|
||||
set(WL_PROTOCOLS_FILE wayland-protocols-${WL_PROTOCOLS_VERSION}.tar.gz)
|
||||
set(WL_PROTOCOLS_URI https://gitlab.freedesktop.org/wayland/wayland-protocols/-/archive/${WL_PROTOCOLS_VERSION}/${WL_PROTOCOLS_FILE})
|
||||
set(WL_PROTOCOLS_HASH af5ca07e13517cdbab33504492cef54a)
|
||||
set(WL_PROTOCOLS_HASH a28ff59a56e2ebb746048b6ef8d931d6)
|
||||
set(WL_PROTOCOLS_HASH_TYPE MD5)
|
||||
|
||||
set(WAYLAND_VERSION 1.21.0)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2022 Blender Foundation. All rights reserved.
|
||||
# Copyright 2022 Blender Foundation
|
||||
|
||||
# This file is used to test the system for headers & symbols.
|
||||
# Variables should use the `HAVE_` prefix.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
macro(list_insert_after
|
||||
list_id item_check item_add
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
|
||||
# Libraries configuration for Apple.
|
||||
|
||||
|
@ -245,6 +245,7 @@ if(WITH_BOOST)
|
|||
if(WITH_USD AND USD_PYTHON_SUPPORT)
|
||||
list(APPEND _boost_FIND_COMPONENTS python${PYTHON_VERSION_NO_DOTS})
|
||||
endif()
|
||||
set(Boost_NO_WARN_NEW_VERSIONS ON)
|
||||
find_package(Boost COMPONENTS ${_boost_FIND_COMPONENTS})
|
||||
|
||||
# Boost Python is separate to avoid linking Python into tests that don't need it.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
|
||||
# Xcode and system configuration for Apple.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2022 Blender Foundation. All rights reserved.
|
||||
# Copyright 2022 Blender Foundation
|
||||
|
||||
# Auto update existing CMake caches for new libraries.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
|
||||
# Libraries configuration for any *nix system including Linux and Unix (excluding APPLE).
|
||||
|
||||
|
@ -394,6 +394,7 @@ if(WITH_BOOST)
|
|||
list(APPEND __boost_packages python${PYTHON_VERSION_NO_DOTS})
|
||||
endif()
|
||||
list(APPEND __boost_packages system)
|
||||
set(Boost_NO_WARN_NEW_VERSIONS ON)
|
||||
find_package(Boost 1.48 COMPONENTS ${__boost_packages})
|
||||
if(NOT Boost_FOUND)
|
||||
# try to find non-multithreaded if -mt not found, this flag
|
||||
|
@ -645,7 +646,7 @@ if(WITH_GHOST_WAYLAND)
|
|||
else()
|
||||
# Rocky8 packages have too old a version, a newer version exist in the pre-compiled libraries.
|
||||
find_path(WAYLAND_PROTOCOLS_DIR
|
||||
NAMES unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
|
||||
NAMES staging/xdg-activation/xdg-activation-v1.xml
|
||||
PATH_SUFFIXES share/wayland-protocols
|
||||
PATHS ${LIBDIR}/wayland-protocols
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
|
||||
# Libraries configuration for Windows.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
# Libs that adhere to strict flags
|
||||
add_subdirectory(curve_fit_nd)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2008 Blender Foundation. All rights reserved.
|
||||
# Copyright 2008 Blender Foundation
|
||||
|
||||
set(INC
|
||||
include
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
# avoid noisy warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2012 Blender Foundation. All rights reserved.
|
||||
# Copyright 2012 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2019 Blender Foundation. All rights reserved.
|
||||
# Copyright 2019 Blender Foundation
|
||||
|
||||
# Build Draco library.
|
||||
add_subdirectory(draco)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Project: fast_float
|
||||
URL: https://github.com/fastfloat/fast_float
|
||||
License: MIT
|
||||
Upstream version: 3.4.0 (b7f9d6c)
|
||||
Upstream version: 4.0.0 (fbd5bd7, 2023 Mar 31)
|
||||
Local modifications:
|
||||
|
||||
- Took only the fast_float.h header and the license/readme files
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
## fast_float number parsing library: 4x faster than strtod
|
||||
|
||||
![Ubuntu 20.04 CI (GCC 9)](https://github.com/lemire/fast_float/workflows/Ubuntu%2020.04%20CI%20(GCC%209)/badge.svg)
|
||||
![Ubuntu 18.04 CI (GCC 7)](https://github.com/lemire/fast_float/workflows/Ubuntu%2018.04%20CI%20(GCC%207)/badge.svg)
|
||||
![Alpine Linux](https://github.com/lemire/fast_float/workflows/Alpine%20Linux/badge.svg)
|
||||
![MSYS2-CI](https://github.com/lemire/fast_float/workflows/MSYS2-CI/badge.svg)
|
||||
![VS16-CLANG-CI](https://github.com/lemire/fast_float/workflows/VS16-CLANG-CI/badge.svg)
|
||||
[![VS16-CI](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/vs16-ci.yml)
|
||||
|
||||
The fast_float library provides fast header-only implementations for the C++ from_chars
|
||||
functions for `float` and `double` types. These functions convert ASCII strings representing
|
||||
decimal values (e.g., `1.3e10`) into binary types. We provide exact rounding (including
|
||||
|
@ -28,8 +21,8 @@ struct from_chars_result {
|
|||
```
|
||||
|
||||
It parses the character sequence [first,last) for a number. It parses floating-point numbers expecting
|
||||
a locale-independent format equivalent to the C++17 from_chars function.
|
||||
The resulting floating-point value is the closest floating-point values (using either float or double),
|
||||
a locale-independent format equivalent to the C++17 from_chars function.
|
||||
The resulting floating-point value is the closest floating-point values (using either float or double),
|
||||
using the "round to even" convention for values that would otherwise fall right in-between two values.
|
||||
That is, we provide exact parsing according to the IEEE standard.
|
||||
|
||||
|
@ -47,7 +40,7 @@ Example:
|
|||
``` C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
int main() {
|
||||
const std::string input = "3.1416 xyz ";
|
||||
double result;
|
||||
|
@ -60,39 +53,60 @@ int main() {
|
|||
|
||||
|
||||
Like the C++17 standard, the `fast_float::from_chars` functions take an optional last argument of
|
||||
the type `fast_float::chars_format`. It is a bitset value: we check whether
|
||||
the type `fast_float::chars_format`. It is a bitset value: we check whether
|
||||
`fmt & fast_float::chars_format::fixed` and `fmt & fast_float::chars_format::scientific` are set
|
||||
to determine whether we allow the fixed point and scientific notation respectively.
|
||||
The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
|
||||
|
||||
The library seeks to follow the C++17 (see [20.19.3](http://eel.is/c++draft/charconv.from.chars).(7.1)) specification.
|
||||
The library seeks to follow the C++17 (see [20.19.3](http://eel.is/c++draft/charconv.from.chars).(7.1)) specification.
|
||||
* The `from_chars` function does not skip leading white-space characters.
|
||||
* [A leading `+` sign](https://en.cppreference.com/w/cpp/utility/from_chars) is forbidden.
|
||||
* It is generally impossible to represent a decimal value exactly as binary floating-point number (`float` and `double` types). We seek the nearest value. We round to an even mantissa when we are in-between two binary floating-point numbers.
|
||||
* It is generally impossible to represent a decimal value exactly as binary floating-point number (`float` and `double` types). We seek the nearest value. We round to an even mantissa when we are in-between two binary floating-point numbers.
|
||||
|
||||
Furthermore, we have the following restrictions:
|
||||
* We only support `float` and `double` types at this time.
|
||||
* We only support the decimal format: we do not support hexadecimal strings.
|
||||
* For values that are either very large or very small (e.g., `1e9999`), we represent it using the infinity or negative infinity value.
|
||||
* For values that are either very large or very small (e.g., `1e9999`), we represent it using the infinity or negative infinity value and the returned `ec` is set to `std::errc::result_out_of_range`.
|
||||
|
||||
We support Visual Studio, macOS, Linux, freeBSD. We support big and little endian. We support 32-bit and 64-bit systems.
|
||||
|
||||
We assume that the rounding mode is set to nearest (`std::fegetround() == FE_TONEAREST`).
|
||||
|
||||
## C++20: compile-time evaluation (constexpr)
|
||||
|
||||
In C++20, you may use `fast_float::from_chars` to parse strings
|
||||
at compile-time, as in the following example:
|
||||
|
||||
```C++
|
||||
// consteval forces compile-time evaluation of the function in C++20.
|
||||
consteval double parse(std::string_view input) {
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) { return -1.0; }
|
||||
return result;
|
||||
}
|
||||
|
||||
// This function should compile to a function which
|
||||
// merely returns 3.1415.
|
||||
constexpr double constexptest() {
|
||||
return parse("3.1415 input");
|
||||
}
|
||||
```
|
||||
|
||||
## Using commas as decimal separator
|
||||
|
||||
|
||||
The C++ standard stipulate that `from_chars` has to be locale-independent. In
|
||||
particular, the decimal separator has to be the period (`.`). However,
|
||||
some users still want to use the `fast_float` library with in a locale-dependent
|
||||
particular, the decimal separator has to be the period (`.`). However,
|
||||
some users still want to use the `fast_float` library with in a locale-dependent
|
||||
manner. Using a separate function called `from_chars_advanced`, we allow the users
|
||||
to pass a `parse_options` instance which contains a custom decimal separator (e.g.,
|
||||
to pass a `parse_options` instance which contains a custom decimal separator (e.g.,
|
||||
the comma). You may use it as follows.
|
||||
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
int main() {
|
||||
const std::string input = "3,1416 xyz ";
|
||||
double result;
|
||||
|
@ -104,25 +118,62 @@ int main() {
|
|||
}
|
||||
```
|
||||
|
||||
You can parse delimited numbers:
|
||||
```C++
|
||||
const std::string input = "234532.3426362,7869234.9823,324562.645";
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) {
|
||||
// check error
|
||||
}
|
||||
// we have result == 234532.3426362.
|
||||
if(answer.ptr[0] != ',') {
|
||||
// unexpected delimiter
|
||||
}
|
||||
answer = fast_float::from_chars(answer.ptr + 1, input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) {
|
||||
// check error
|
||||
}
|
||||
// we have result == 7869234.9823.
|
||||
if(answer.ptr[0] != ',') {
|
||||
// unexpected delimiter
|
||||
}
|
||||
answer = fast_float::from_chars(answer.ptr + 1, input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) {
|
||||
// check error
|
||||
}
|
||||
// we have result == 324562.645.
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Pratice and Experience 51 (8), 2021.
|
||||
## Relation With Other Work
|
||||
|
||||
The fast_float library is part of:
|
||||
|
||||
- GCC (as of version 12): the `from_chars` function in GCC relies on fast_float.
|
||||
- [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's web browser)
|
||||
|
||||
|
||||
The fastfloat algorithm is part of the [LLVM standard libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba).
|
||||
|
||||
There is a [derived implementation part of AdaCore](https://github.com/AdaCore/VSS).
|
||||
|
||||
|
||||
The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM).
|
||||
|
||||
## References
|
||||
|
||||
- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Practice and Experience 51 (8), 2021.
|
||||
- Noble Mushtak, Daniel Lemire, [Fast Number Parsing Without Fallback](https://arxiv.org/abs/2212.06644), Software: Practice and Experience (to appear)
|
||||
|
||||
## Other programming languages
|
||||
|
||||
- [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called `rcppfastfloat`.
|
||||
- [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`.
|
||||
- [There is a Java port of the fast_float library](https://github.com/wrandelshofer/FastDoubleParser) called `FastDoubleParser`.
|
||||
- [There is a Java port of the fast_float library](https://github.com/wrandelshofer/FastDoubleParser) called `FastDoubleParser`. It used for important systems such as [Jackson](https://github.com/FasterXML/jackson-core).
|
||||
- [There is a C# port of the fast_float library](https://github.com/CarlVerret/csFastFloat) called `csFastFloat`.
|
||||
|
||||
|
||||
## Relation With Other Work
|
||||
|
||||
The fastfloat algorithm is part of the [LLVM standard libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba).
|
||||
|
||||
The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM).
|
||||
|
||||
## Users
|
||||
|
||||
The fast_float library is used by [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied the number parsing speed by two or three times. It is also used by [Yandex ClickHouse](https://github.com/ClickHouse/ClickHouse) and by [Google Jsonnet](https://github.com/google/jsonnet).
|
||||
|
@ -135,14 +186,14 @@ It can parse random floating-point numbers at a speed of 1 GB/s on some systems.
|
|||
<img src="http://lemire.me/blog/wp-content/uploads/2020/11/fastfloat_speed.png" width="400">
|
||||
|
||||
```
|
||||
$ ./build/benchmarks/benchmark
|
||||
$ ./build/benchmarks/benchmark
|
||||
# parsing random integers in the range [0,1)
|
||||
volume = 2.09808 MB
|
||||
netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s
|
||||
doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s
|
||||
strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s
|
||||
abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s
|
||||
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
|
||||
volume = 2.09808 MB
|
||||
netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s
|
||||
doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s
|
||||
strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s
|
||||
abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s
|
||||
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
|
||||
```
|
||||
|
||||
See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code.
|
||||
|
@ -183,23 +234,23 @@ You should change the `GIT_TAG` line so that you recover the version you wish to
|
|||
|
||||
## Using as single header
|
||||
|
||||
The script `script/amalgamate.py` may be used to generate a single header
|
||||
The script `script/amalgamate.py` may be used to generate a single header
|
||||
version of the library if so desired.
|
||||
Just run the script from the root directory of this repository.
|
||||
Just run the script from the root directory of this repository.
|
||||
You can customize the license type and output file if desired as described in
|
||||
the command line help.
|
||||
|
||||
You may directly download automatically generated single-header files:
|
||||
|
||||
https://github.com/fastfloat/fast_float/releases/download/v1.1.2/fast_float.h
|
||||
https://github.com/fastfloat/fast_float/releases/download/v3.4.0/fast_float.h
|
||||
|
||||
## Credit
|
||||
|
||||
Though this work is inspired by many different people, this work benefited especially from exchanges with
|
||||
Michael Eisel, who motivated the original research with his key insights, and with Nigel Tao who provided
|
||||
Though this work is inspired by many different people, this work benefited especially from exchanges with
|
||||
Michael Eisel, who motivated the original research with his key insights, and with Nigel Tao who provided
|
||||
invaluable feedback. Rémy Oudompheng first implemented a fast path we use in the case of long digits.
|
||||
|
||||
The library includes code adapted from Google Wuffs (written by Nigel Tao) which was originally published
|
||||
The library includes code adapted from Google Wuffs (written by Nigel Tao) which was originally published
|
||||
under the Apache 2.0 license.
|
||||
|
||||
## License
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
|
||||
# Too noisy for code we don't maintain.
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
|
||||
set(INC
|
||||
src
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2014 Blender Foundation. All rights reserved.
|
||||
# Copyright 2014 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2014 Blender Foundation. All rights reserved.
|
||||
# Copyright 2014 Blender Foundation
|
||||
|
||||
# avoid noisy warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2021 Blender Foundation. All rights reserved.
|
||||
# Copyright 2021 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
# avoid noisy warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
remove_strict_flags()
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2016 Blender Foundation. All rights reserved.
|
||||
# Copyright 2016 Blender Foundation
|
||||
# The Original Code is: all of this file.
|
||||
# Contributor(s): Sebastian Barschkis (sebbas).
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2019 Blender Foundation. All rights reserved.
|
||||
# Copyright 2019 Blender Foundation
|
||||
|
||||
# avoid noisy warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2017 Blender Foundation. All rights reserved.
|
||||
# Copyright 2017 Blender Foundation
|
||||
# The Original Code is: all of this file.
|
||||
# Contributor(s): IRIE Shinsuke.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2022 Blender Foundation. All rights reserved.
|
||||
# Copyright 2022 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2022 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2022 Blender Foundation */
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <MoltenVK/vk_mvk_moltenvk.h>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2013 Blender Foundation. All rights reserved.
|
||||
# Copyright 2013 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2012 Blender Foundation. All rights reserved.
|
||||
# Copyright 2012 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
# add_subdirectory(atomic) # header only
|
||||
add_subdirectory(atomic)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2020 Blender Foundation. All rights reserved.
|
||||
# Copyright 2020 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -38,10 +38,8 @@
|
|||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: adapted from jemalloc.
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
|
|
@ -38,10 +38,8 @@
|
|||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: adapted from jemalloc.
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
|
|
@ -38,10 +38,8 @@
|
|||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: adapted from jemalloc.
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
|
|
@ -38,10 +38,8 @@
|
|||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: adapted from jemalloc.
|
||||
* The Original Code is adapted from jemalloc.
|
||||
* Modifications Copyright (C) 2016 Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
|
|
|
@ -590,11 +590,10 @@ bool MetalDeviceQueue::enqueue(DeviceKernel kernel,
|
|||
[mtlComputeCommandEncoder setThreadgroupMemoryLength:shared_mem_bytes atIndex:0];
|
||||
}
|
||||
|
||||
MTLSize size_threadgroups_per_dispatch = MTLSizeMake(
|
||||
divide_up(work_size, num_threads_per_block), 1, 1);
|
||||
MTLSize size_threads_per_dispatch = MTLSizeMake(work_size, 1, 1);
|
||||
MTLSize size_threads_per_threadgroup = MTLSizeMake(num_threads_per_block, 1, 1);
|
||||
[mtlComputeCommandEncoder dispatchThreadgroups:size_threadgroups_per_dispatch
|
||||
threadsPerThreadgroup:size_threads_per_threadgroup];
|
||||
[mtlComputeCommandEncoder dispatchThreads:size_threads_per_dispatch
|
||||
threadsPerThreadgroup:size_threads_per_threadgroup];
|
||||
|
||||
[mtlCommandBuffer_ addCompletedHandler:^(id<MTLCommandBuffer> command_buffer) {
|
||||
NSString *kernel_name = metal_kernel_pso->function.label;
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define ccl_gpu_kernel_postfix
|
||||
|
||||
#define ccl_gpu_kernel_call(x) x
|
||||
#define ccl_gpu_kernel_within_bounds(i, n) ((i) < (n))
|
||||
|
||||
/* Define a function object where "func" is the lambda body, and additional parameters are used to
|
||||
* specify captured state */
|
||||
|
|
|
@ -136,7 +136,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_intersect_closest(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_intersect_shadow(NULL, state));
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_intersect_subsurface(NULL, state));
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_intersect_volume_stack(NULL, state));
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_shade_background(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_shade_light(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_shade_shadow(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_shade_surface(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
|
||||
#if defined(__KERNEL_METAL_APPLE__) && defined(__METALRT__)
|
||||
|
@ -281,7 +281,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_shade_surface_mnee(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||
ccl_gpu_kernel_call(integrator_shade_volume(NULL, state, render_buffer));
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int from_state = active_terminated_states[active_states_offset + global_index];
|
||||
const int to_state = active_terminated_states[terminated_states_offset + global_index];
|
||||
|
||||
|
@ -526,7 +526,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
|
|||
{
|
||||
const int global_index = ccl_gpu_global_id_x();
|
||||
|
||||
if (global_index < work_size) {
|
||||
if (ccl_gpu_kernel_within_bounds(global_index, work_size)) {
|
||||
const int from_state = active_terminated_states[active_states_offset + global_index];
|
||||
const int to_state = active_terminated_states[terminated_states_offset + global_index];
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#define ccl_gpu_kernel_postfix
|
||||
|
||||
#define ccl_gpu_kernel_call(x) x
|
||||
#define ccl_gpu_kernel_within_bounds(i, n) ((i) < (n))
|
||||
|
||||
/* Define a function object where "func" is the lambda body, and additional parameters are used to
|
||||
* specify captured state */
|
||||
|
|
|
@ -143,6 +143,7 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
|
|||
|
||||
#define ccl_gpu_kernel_postfix
|
||||
#define ccl_gpu_kernel_call(x) context.x
|
||||
#define ccl_gpu_kernel_within_bounds(i,n) true
|
||||
|
||||
/* define a function object where "func" is the lambda body, and additional parameters are used to specify captured state */
|
||||
#define ccl_gpu_kernel_lambda(func, ...) \
|
||||
|
|
|
@ -289,9 +289,8 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal,
|
|||
}
|
||||
|
||||
if (ray_tmax >= max_recorded_t) {
|
||||
/* Accept hit, so that we don't consider any more hits beyond the distance of the
|
||||
* current hit anymore. */
|
||||
payload.result = true;
|
||||
/* Ray hits are not guaranteed to be ordered by distance so don't exit early here.
|
||||
* Continue search. */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \
|
|||
#endif
|
||||
|
||||
#define ccl_gpu_kernel_call(x) ((ONEAPIKernelContext*)kg)->x
|
||||
#define ccl_gpu_kernel_within_bounds(i, n) ((i) < (n))
|
||||
|
||||
#define ccl_gpu_kernel_lambda(func, ...) \
|
||||
struct KernelLambda \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2015 Blender Foundation. All rights reserved.
|
||||
# Copyright 2015 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2015 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2015 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2015 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2015 Blender Foundation */
|
||||
|
||||
#ifndef __EIGEN3_EIGENVALUES_C_API_CC__
|
||||
#define __EIGEN3_EIGENVALUES_C_API_CC__
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2015 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2015 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2018 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2018 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2015 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2015 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2015 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2015 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2015 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2015 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_eigen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2020 Blender Foundation. All rights reserved.
|
||||
# Copyright 2020 Blender Foundation
|
||||
|
||||
if(WITH_GTESTS)
|
||||
set(TEST_SRC
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
@ -378,6 +378,14 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
|||
unset(_name)
|
||||
endmacro()
|
||||
|
||||
macro(generate_protocol_bindings_when_found PROT_DEF FOUND_VAR)
|
||||
if(EXISTS ${PROT_DEF})
|
||||
generate_protocol_bindings(${PROT_DEF})
|
||||
set(${FOUND_VAR} TRUE)
|
||||
else()
|
||||
set(${FOUND_VAR} FALSE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
list(APPEND INC_SYS
|
||||
${INC_DST}
|
||||
|
@ -402,6 +410,17 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
|||
generate_protocol_bindings(
|
||||
"${WAYLAND_PROTOCOLS_DIR}/staging/xdg-activation/xdg-activation-v1.xml"
|
||||
)
|
||||
# Fractional scale.
|
||||
generate_protocol_bindings_when_found(
|
||||
"${WAYLAND_PROTOCOLS_DIR}/staging/fractional-scale/fractional-scale-v1.xml"
|
||||
_has_fractional_scale
|
||||
)
|
||||
if(_has_fractional_scale)
|
||||
# Viewport (only required when fractional scale is in use).
|
||||
generate_protocol_bindings(
|
||||
"${WAYLAND_PROTOCOLS_DIR}/stable/viewporter/viewporter.xml"
|
||||
)
|
||||
endif()
|
||||
# Pointer-constraints.
|
||||
generate_protocol_bindings(
|
||||
"${WAYLAND_PROTOCOLS_DIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
|
||||
|
@ -427,6 +446,11 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
|||
|
||||
add_definitions(-DWITH_GHOST_WAYLAND)
|
||||
|
||||
if(_has_fractional_scale)
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_FRACTIONAL_SCALE)
|
||||
endif()
|
||||
unset(_has_fractional_scale)
|
||||
|
||||
if(NOT WITH_GHOST_WAYLAND_APP_ID STREQUAL "")
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_APP_ID=${WITH_GHOST_WAYLAND_APP_ID})
|
||||
endif()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2009 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2009 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2012 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2012 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2012 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2012 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2009 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2009 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2010 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2010 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2011 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2011 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
|
|
|
@ -61,6 +61,10 @@
|
|||
#include <tablet-unstable-v2-client-protocol.h>
|
||||
#include <xdg-activation-v1-client-protocol.h>
|
||||
#include <xdg-output-unstable-v1-client-protocol.h>
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
# include <fractional-scale-v1-client-protocol.h>
|
||||
# include <viewporter-client-protocol.h>
|
||||
#endif
|
||||
|
||||
/* Decorations `xdg_decor`. */
|
||||
#include <xdg-decoration-unstable-v1-client-protocol.h>
|
||||
|
@ -205,6 +209,14 @@ static bool use_gnome_confine_hack = false;
|
|||
|
||||
#define WL_NAME_UNSET uint32_t(-1)
|
||||
|
||||
/**
|
||||
* Initializer for GHOST integer coordinates from `wl_fixed_t`,
|
||||
* taking window scale into account.
|
||||
*/
|
||||
#define WL_FIXED_TO_INT_FOR_WINDOW_V2(win, xy) \
|
||||
wl_fixed_to_int((win)->wl_fixed_to_window((xy)[0])), \
|
||||
wl_fixed_to_int((win)->wl_fixed_to_window((xy)[1])),
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -936,6 +948,10 @@ struct GWL_Display {
|
|||
struct zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr;
|
||||
struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr;
|
||||
struct xdg_activation_v1 *xdg_activation_manager = nullptr;
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr;
|
||||
struct wp_viewporter *wp_viewporter = nullptr;
|
||||
#endif
|
||||
|
||||
struct zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr;
|
||||
struct zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr;
|
||||
|
@ -1925,8 +1941,6 @@ static void relative_pointer_handle_relative_motion_impl(GWL_Seat *seat,
|
|||
GHOST_WindowWayland *win,
|
||||
const wl_fixed_t xy[2])
|
||||
{
|
||||
const wl_fixed_t scale = win->scale();
|
||||
|
||||
seat->pointer.xy[0] = xy[0];
|
||||
seat->pointer.xy[1] = xy[1];
|
||||
|
||||
|
@ -1937,21 +1951,19 @@ static void relative_pointer_handle_relative_motion_impl(GWL_Seat *seat,
|
|||
/* Needed or the cursor is considered outside the window and doesn't restore the location. */
|
||||
bounds.m_r -= 1;
|
||||
bounds.m_b -= 1;
|
||||
|
||||
bounds.m_l = wl_fixed_from_int(bounds.m_l) / scale;
|
||||
bounds.m_t = wl_fixed_from_int(bounds.m_t) / scale;
|
||||
bounds.m_r = wl_fixed_from_int(bounds.m_r) / scale;
|
||||
bounds.m_b = wl_fixed_from_int(bounds.m_b) / scale;
|
||||
bounds.m_l = win->wl_fixed_from_window(wl_fixed_from_int(bounds.m_l));
|
||||
bounds.m_t = win->wl_fixed_from_window(wl_fixed_from_int(bounds.m_t));
|
||||
bounds.m_r = win->wl_fixed_from_window(wl_fixed_from_int(bounds.m_r));
|
||||
bounds.m_b = win->wl_fixed_from_window(wl_fixed_from_int(bounds.m_b));
|
||||
bounds.clampPoint(UNPACK2(seat->pointer.xy));
|
||||
}
|
||||
#endif
|
||||
seat->system->pushEvent_maybe_pending(
|
||||
new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[0]),
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[1]),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->pointer.xy)};
|
||||
seat->system->pushEvent_maybe_pending(new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
UNPACK2(event_xy),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
|
||||
static void relative_pointer_handle_relative_motion(
|
||||
|
@ -1968,10 +1980,9 @@ static void relative_pointer_handle_relative_motion(
|
|||
if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
|
||||
CLOG_INFO(LOG, 2, "relative_motion");
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
const wl_fixed_t scale = win->scale();
|
||||
const wl_fixed_t xy_next[2] = {
|
||||
seat->pointer.xy[0] + (dx / scale),
|
||||
seat->pointer.xy[1] + (dy / scale),
|
||||
seat->pointer.xy[0] + win->wl_fixed_from_window(dx),
|
||||
seat->pointer.xy[1] + win->wl_fixed_from_window(dy),
|
||||
};
|
||||
relative_pointer_handle_relative_motion_impl(seat, win, xy_next);
|
||||
}
|
||||
|
@ -2000,12 +2011,7 @@ static void dnd_events(const GWL_Seat *const seat, const GHOST_TEventType event)
|
|||
/* NOTE: `seat->data_offer_dnd_mutex` must already be locked. */
|
||||
if (wl_surface *wl_surface_focus = seat->wl_surface_window_focus_dnd) {
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
const wl_fixed_t scale = win->scale();
|
||||
const int event_xy[2] = {
|
||||
wl_fixed_to_int(scale * seat->data_offer_dnd->dnd.xy[0]),
|
||||
wl_fixed_to_int(scale * seat->data_offer_dnd->dnd.xy[1]),
|
||||
};
|
||||
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->data_offer_dnd->dnd.xy)};
|
||||
const uint64_t time = seat->system->getMilliSeconds();
|
||||
for (size_t i = 0; i < ARRAY_SIZE(ghost_wl_mime_preference_order_type); i++) {
|
||||
const GHOST_TDragnDropTypes type = ghost_wl_mime_preference_order_type[i];
|
||||
|
@ -2477,13 +2483,12 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat
|
|||
}
|
||||
|
||||
CLOG_INFO(LOG, 2, "drop_read_uris_fn file_count=%d", flist->count);
|
||||
const wl_fixed_t scale = win->scale();
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, xy)};
|
||||
system->pushEvent_maybe_pending(new GHOST_EventDragnDrop(system->getMilliSeconds(),
|
||||
GHOST_kEventDraggingDropDone,
|
||||
GHOST_kDragnDropTypeFilenames,
|
||||
win,
|
||||
wl_fixed_to_int(scale * xy[0]),
|
||||
wl_fixed_to_int(scale * xy[1]),
|
||||
UNPACK2(event_xy),
|
||||
flist));
|
||||
}
|
||||
else if (ELEM(mime_receive, ghost_wl_mime_text_plain, ghost_wl_mime_text_utf8)) {
|
||||
|
@ -2685,14 +2690,12 @@ static void pointer_handle_enter(void *data,
|
|||
|
||||
seat->system->cursor_shape_set(win->getCursorShape());
|
||||
|
||||
const wl_fixed_t scale = win->scale();
|
||||
seat->system->pushEvent_maybe_pending(
|
||||
new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[0]),
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[1]),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->pointer.xy)};
|
||||
seat->system->pushEvent_maybe_pending(new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
UNPACK2(event_xy),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
|
||||
static void pointer_handle_leave(void *data,
|
||||
|
@ -2723,14 +2726,12 @@ static void pointer_handle_motion(void *data,
|
|||
if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
|
||||
CLOG_INFO(LOG, 2, "motion");
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
const wl_fixed_t scale = win->scale();
|
||||
seat->system->pushEvent_maybe_pending(
|
||||
new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[0]),
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[1]),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->pointer.xy)};
|
||||
seat->system->pushEvent_maybe_pending(new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
UNPACK2(event_xy),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
else {
|
||||
CLOG_INFO(LOG, 2, "motion (skipped)");
|
||||
|
@ -2849,13 +2850,12 @@ static void pointer_handle_frame(void *data, struct wl_pointer * /*wl_pointer*/)
|
|||
if (seat->pointer_scroll.smooth_xy[0] || seat->pointer_scroll.smooth_xy[1]) {
|
||||
if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
const wl_fixed_t scale = win->scale();
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->pointer.xy)};
|
||||
seat->system->pushEvent_maybe_pending(new GHOST_EventTrackpad(
|
||||
seat->system->getMilliSeconds(),
|
||||
win,
|
||||
GHOST_kTrackpadEventScroll,
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[0]),
|
||||
wl_fixed_to_int(scale * seat->pointer.xy[1]),
|
||||
UNPACK2(event_xy),
|
||||
/* NOTE: scaling the delta doesn't seem necessary.
|
||||
* NOTE: inverting delta gives correct results, see: QTBUG-85767.
|
||||
* NOTE: the preference to invert scrolling (in GNOME at least)
|
||||
|
@ -3014,19 +3014,6 @@ static void gesture_pinch_handle_begin(void *data,
|
|||
if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
|
||||
win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
}
|
||||
/* NOTE(@ideasman42): Blender's use of track-pad coordinates is inconsistent and needs work.
|
||||
* This isn't specific to WAYLAND, in practice they tend to work well enough in most cases.
|
||||
* Some operators scale by the UI scale, some don't.
|
||||
* Even this window scale is not correct because it doesn't account for:
|
||||
* 1) Fractional window scale.
|
||||
* 2) Blender's UI scale preference (which GHOST doesn't know about).
|
||||
*
|
||||
* If support for this were all that was needed it could be handled in GHOST,
|
||||
* however as the operators are not even using coordinates compatible with each other,
|
||||
* it would be better to resolve this by passing rotation & zoom levels directly,
|
||||
* instead of attempting to handle them as cursor coordinates.
|
||||
*/
|
||||
const wl_fixed_t win_scale = win ? win->scale() : 1;
|
||||
|
||||
/* NOTE(@ideasman42): Scale factors match Blender's operators & default preferences.
|
||||
* For these values to work correctly, operator logic will need to be changed not to scale input
|
||||
|
@ -3041,10 +3028,30 @@ static void gesture_pinch_handle_begin(void *data,
|
|||
seat->pointer_gesture_pinch.scale.value = wl_fixed_from_int(1);
|
||||
/* The value 300 matches a value used in clip & image zoom operators.
|
||||
* It seems OK for the 3D view too. */
|
||||
seat->pointer_gesture_pinch.scale.factor = 300 * win_scale;
|
||||
seat->pointer_gesture_pinch.scale.factor = 300;
|
||||
/* The value 5 is used on macOS and roughly maps 1:1 with turntable rotation,
|
||||
* although preferences can scale the sensitivity (which would be skipped ideally). */
|
||||
seat->pointer_gesture_pinch.rotation.factor = 5 * win_scale;
|
||||
seat->pointer_gesture_pinch.rotation.factor = 5;
|
||||
|
||||
if (win) {
|
||||
/* NOTE(@ideasman42): Blender's use of track-pad coordinates is inconsistent and needs work.
|
||||
* This isn't specific to WAYLAND, in practice they tend to work well enough in most cases.
|
||||
* Some operators scale by the UI scale, some don't.
|
||||
* Even this window scale is not correct because it doesn't account for:
|
||||
* 1) Fractional window scale.
|
||||
* 2) Blender's UI scale preference (which GHOST doesn't know about).
|
||||
*
|
||||
* If support for this were all that was needed it could be handled in GHOST,
|
||||
* however as the operators are not even using coordinates compatible with each other,
|
||||
* it would be better to resolve this by passing rotation & zoom levels directly,
|
||||
* instead of attempting to handle them as cursor coordinates.
|
||||
*/
|
||||
const struct GWL_WindowScaleParams &scale_params = win->scale_params();
|
||||
seat->pointer_gesture_pinch.scale.factor = gwl_window_scale_int_to(
|
||||
scale_params, seat->pointer_gesture_pinch.scale.factor);
|
||||
seat->pointer_gesture_pinch.rotation.factor = gwl_window_scale_int_to(
|
||||
scale_params, seat->pointer_gesture_pinch.rotation.factor);
|
||||
}
|
||||
}
|
||||
|
||||
static void gesture_pinch_handle_update(void *data,
|
||||
|
@ -3082,11 +3089,7 @@ static void gesture_pinch_handle_update(void *data,
|
|||
&seat->pointer_gesture_pinch.rotation, rotation);
|
||||
|
||||
if (win) {
|
||||
const wl_fixed_t win_scale = win->scale();
|
||||
const int32_t event_xy[2] = {
|
||||
wl_fixed_to_int(win_scale * seat->pointer.xy[0]),
|
||||
wl_fixed_to_int(win_scale * seat->pointer.xy[1]),
|
||||
};
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->pointer.xy)};
|
||||
if (scale_as_delta_px) {
|
||||
seat->system->pushEvent_maybe_pending(
|
||||
new GHOST_EventTrackpad(seat->system->getMilliSeconds(),
|
||||
|
@ -3566,14 +3569,12 @@ static void tablet_tool_handle_frame(void *data,
|
|||
/* No need to check the surfaces origin, it's already known to be owned by GHOST. */
|
||||
if (wl_surface *wl_surface_focus = seat->tablet.wl_surface_window) {
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
const wl_fixed_t scale = win->scale();
|
||||
seat->system->pushEvent_maybe_pending(
|
||||
new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
wl_fixed_to_int(scale * seat->tablet.xy[0]),
|
||||
wl_fixed_to_int(scale * seat->tablet.xy[1]),
|
||||
tablet_tool->data));
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, seat->tablet.xy)};
|
||||
seat->system->pushEvent_maybe_pending(new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
win,
|
||||
UNPACK2(event_xy),
|
||||
tablet_tool->data));
|
||||
if (tablet_tool->proximity == false) {
|
||||
seat->system->cursor_shape_set(win->getCursorShape());
|
||||
}
|
||||
|
@ -5181,6 +5182,47 @@ static void gwl_registry_xdg_activation_remove(GWL_Display *display,
|
|||
*value_p = nullptr;
|
||||
}
|
||||
|
||||
/* #GWL_Display.wp_fractional_scale_manger */
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
|
||||
static void gwl_registry_wp_fractional_scale_manager_add(GWL_Display *display,
|
||||
const GWL_RegisteryAdd_Params *params)
|
||||
{
|
||||
display->wp_fractional_scale_manager = static_cast<wp_fractional_scale_manager_v1 *>(
|
||||
wl_registry_bind(
|
||||
display->wl_registry, params->name, &wp_fractional_scale_manager_v1_interface, 1));
|
||||
gwl_registry_entry_add(display, params, nullptr);
|
||||
}
|
||||
static void gwl_registry_wp_fractional_scale_manager_remove(GWL_Display *display,
|
||||
void * /*user_data*/,
|
||||
const bool /*on_exit*/)
|
||||
{
|
||||
struct wp_fractional_scale_manager_v1 **value_p = &display->wp_fractional_scale_manager;
|
||||
wp_fractional_scale_manager_v1_destroy(*value_p);
|
||||
*value_p = nullptr;
|
||||
}
|
||||
|
||||
/* #GWL_Display.wl_viewport */
|
||||
|
||||
static void gwl_registry_wp_viewporter_add(GWL_Display *display,
|
||||
const GWL_RegisteryAdd_Params *params)
|
||||
{
|
||||
display->wp_viewporter = static_cast<wp_viewporter *>(
|
||||
wl_registry_bind(display->wl_registry, params->name, &wp_viewporter_interface, 1));
|
||||
gwl_registry_entry_add(display, params, nullptr);
|
||||
}
|
||||
static void gwl_registry_wp_viewporter_remove(GWL_Display *display,
|
||||
void * /*user_data*/,
|
||||
const bool /*on_exit*/)
|
||||
{
|
||||
struct wp_viewporter **value_p = &display->wp_viewporter;
|
||||
wp_viewporter_destroy(*value_p);
|
||||
*value_p = nullptr;
|
||||
}
|
||||
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
/* #GWL_Display.wp_primary_selection_device_manager */
|
||||
|
||||
static void gwl_registry_wp_primary_selection_device_manager_add(
|
||||
|
@ -5290,6 +5332,20 @@ static const GWL_RegistryHandler gwl_registry_handlers[] = {
|
|||
/*update_fn*/ nullptr,
|
||||
/*remove_fn*/ gwl_registry_xdg_activation_remove,
|
||||
},
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
{
|
||||
/*interface_p*/ &wp_fractional_scale_manager_v1_interface.name,
|
||||
/*add_fn*/ gwl_registry_wp_fractional_scale_manager_add,
|
||||
/*update_fn*/ nullptr,
|
||||
/*remove_fn*/ gwl_registry_wp_fractional_scale_manager_remove,
|
||||
},
|
||||
{
|
||||
/*interface_p*/ &wp_viewporter_interface.name,
|
||||
/*add_fn*/ gwl_registry_wp_viewporter_add,
|
||||
/*update_fn*/ nullptr,
|
||||
/*remove_fn*/ gwl_registry_wp_viewporter_remove,
|
||||
},
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
/* Display outputs. */
|
||||
{
|
||||
/*interface_p*/ &wl_output_interface.name,
|
||||
|
@ -6020,7 +6076,6 @@ static GHOST_TSuccess getCursorPositionClientRelative_impl(
|
|||
int32_t &x,
|
||||
int32_t &y)
|
||||
{
|
||||
const wl_fixed_t scale = win->scale();
|
||||
|
||||
if (win->getCursorGrabModeIsWarp()) {
|
||||
/* As the cursor is restored at the warped location,
|
||||
|
@ -6037,18 +6092,19 @@ static GHOST_TSuccess getCursorPositionClientRelative_impl(
|
|||
};
|
||||
|
||||
GHOST_Rect wrap_bounds_scale;
|
||||
wrap_bounds_scale.m_l = wl_fixed_from_int(wrap_bounds.m_l) / scale;
|
||||
wrap_bounds_scale.m_t = wl_fixed_from_int(wrap_bounds.m_t) / scale;
|
||||
wrap_bounds_scale.m_r = wl_fixed_from_int(wrap_bounds.m_r) / scale;
|
||||
wrap_bounds_scale.m_b = wl_fixed_from_int(wrap_bounds.m_b) / scale;
|
||||
|
||||
wrap_bounds_scale.m_l = win->wl_fixed_from_window(wl_fixed_from_int(wrap_bounds.m_l));
|
||||
wrap_bounds_scale.m_t = win->wl_fixed_from_window(wl_fixed_from_int(wrap_bounds.m_t));
|
||||
wrap_bounds_scale.m_r = win->wl_fixed_from_window(wl_fixed_from_int(wrap_bounds.m_r));
|
||||
wrap_bounds_scale.m_b = win->wl_fixed_from_window(wl_fixed_from_int(wrap_bounds.m_b));
|
||||
wrap_bounds_scale.wrapPoint(UNPACK2(xy_wrap), 0, win->getCursorGrabAxis());
|
||||
|
||||
x = wl_fixed_to_int(scale * xy_wrap[0]);
|
||||
y = wl_fixed_to_int(scale * xy_wrap[1]);
|
||||
x = wl_fixed_to_int(win->wl_fixed_to_window(xy_wrap[0]));
|
||||
y = wl_fixed_to_int(win->wl_fixed_to_window(xy_wrap[1]));
|
||||
}
|
||||
else {
|
||||
x = wl_fixed_to_int(scale * seat_state_pointer->xy[0]);
|
||||
y = wl_fixed_to_int(scale * seat_state_pointer->xy[1]);
|
||||
x = win->wl_fixed_to_window(seat_state_pointer->xy[0]);
|
||||
y = win->wl_fixed_to_window(seat_state_pointer->xy[1]);
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
|
@ -6065,10 +6121,9 @@ static GHOST_TSuccess setCursorPositionClientRelative_impl(GWL_Seat *seat,
|
|||
if (!seat->wp_relative_pointer) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
const wl_fixed_t scale = win->scale();
|
||||
const wl_fixed_t xy_next[2] = {
|
||||
wl_fixed_from_int(x) / scale,
|
||||
wl_fixed_from_int(y) / scale,
|
||||
const wl_fixed_t xy_next[2]{
|
||||
win->wl_fixed_from_window(wl_fixed_from_int(x)),
|
||||
win->wl_fixed_from_window(wl_fixed_from_int(y)),
|
||||
};
|
||||
|
||||
/* As the cursor was "warped" generate an event at the new location. */
|
||||
|
@ -6855,6 +6910,17 @@ struct xdg_activation_v1 *GHOST_SystemWayland::xdg_activation_manager()
|
|||
return display_->xdg_activation_manager;
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
struct wp_fractional_scale_manager_v1 *GHOST_SystemWayland::wp_fractional_scale_manager()
|
||||
{
|
||||
return display_->wp_fractional_scale_manager;
|
||||
}
|
||||
struct wp_viewporter *GHOST_SystemWayland::wp_viewporter()
|
||||
{
|
||||
return display_->wp_viewporter;
|
||||
}
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
struct zwp_pointer_gestures_v1 *GHOST_SystemWayland::wp_pointer_gestures()
|
||||
{
|
||||
return display_->wp_pointer_gestures;
|
||||
|
@ -7070,7 +7136,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||
const GHOST_Rect *wrap_bounds,
|
||||
const GHOST_TAxisFlag wrap_axis,
|
||||
wl_surface *wl_surface,
|
||||
const int scale)
|
||||
const struct GWL_WindowScaleParams &scale_params)
|
||||
{
|
||||
/* Caller must lock `server_mutex`. */
|
||||
|
||||
|
@ -7130,10 +7196,14 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||
|
||||
GHOST_Rect bounds_scale;
|
||||
|
||||
bounds_scale.m_l = wl_fixed_from_int(wrap_bounds->m_l) / scale;
|
||||
bounds_scale.m_t = wl_fixed_from_int(wrap_bounds->m_t) / scale;
|
||||
bounds_scale.m_r = wl_fixed_from_int(wrap_bounds->m_r) / scale;
|
||||
bounds_scale.m_b = wl_fixed_from_int(wrap_bounds->m_b) / scale;
|
||||
bounds_scale.m_l = gwl_window_scale_wl_fixed_from(scale_params,
|
||||
wl_fixed_from_int(wrap_bounds->m_l));
|
||||
bounds_scale.m_t = gwl_window_scale_wl_fixed_from(scale_params,
|
||||
wl_fixed_from_int(wrap_bounds->m_t));
|
||||
bounds_scale.m_r = gwl_window_scale_wl_fixed_from(scale_params,
|
||||
wl_fixed_from_int(wrap_bounds->m_r));
|
||||
bounds_scale.m_b = gwl_window_scale_wl_fixed_from(scale_params,
|
||||
wl_fixed_from_int(wrap_bounds->m_b));
|
||||
|
||||
bounds_scale.wrapPoint(UNPACK2(xy_next), 0, wrap_axis);
|
||||
|
||||
|
@ -7153,8 +7223,8 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||
if ((init_grab_xy[0] != seat->grab_lock_xy[0]) ||
|
||||
(init_grab_xy[1] != seat->grab_lock_xy[1])) {
|
||||
const wl_fixed_t xy_next[2] = {
|
||||
wl_fixed_from_int(init_grab_xy[0]) / scale,
|
||||
wl_fixed_from_int(init_grab_xy[1]) / scale,
|
||||
gwl_window_scale_wl_fixed_from(scale_params, wl_fixed_from_int(init_grab_xy[0])),
|
||||
gwl_window_scale_wl_fixed_from(scale_params, wl_fixed_from_int(init_grab_xy[1])),
|
||||
};
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(seat->wp_locked_pointer,
|
||||
UNPACK2(xy_next));
|
||||
|
@ -7179,13 +7249,13 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||
#endif
|
||||
|
||||
if (xy_motion_create_event) {
|
||||
seat->system->pushEvent_maybe_pending(
|
||||
new GHOST_EventCursor(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
ghost_wl_surface_user_data(wl_surface),
|
||||
wl_fixed_to_int(scale * xy_motion[0]),
|
||||
wl_fixed_to_int(scale * xy_motion[1]),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
seat->system->pushEvent_maybe_pending(new GHOST_EventCursor(
|
||||
seat->system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
ghost_wl_surface_user_data(wl_surface),
|
||||
wl_fixed_to_int(gwl_window_scale_wl_fixed_to(scale_params, xy_motion[0])),
|
||||
wl_fixed_to_int(gwl_window_scale_wl_fixed_to(scale_params, xy_motion[1])),
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
|
||||
zwp_locked_pointer_v1_destroy(seat->wp_locked_pointer);
|
||||
|
@ -7221,8 +7291,10 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||
if (mode == GHOST_kGrabHide) {
|
||||
/* Set the initial position to detect any changes when un-grabbing,
|
||||
* otherwise the unlocked cursor defaults to un-locking in-place. */
|
||||
init_grab_xy[0] = wl_fixed_to_int(scale * seat->pointer.xy[0]);
|
||||
init_grab_xy[1] = wl_fixed_to_int(scale * seat->pointer.xy[1]);
|
||||
init_grab_xy[0] = wl_fixed_to_int(
|
||||
gwl_window_scale_wl_fixed_to(scale_params, seat->pointer.xy[0]));
|
||||
init_grab_xy[1] = wl_fixed_to_int(
|
||||
gwl_window_scale_wl_fixed_to(scale_params, seat->pointer.xy[1]));
|
||||
seat->grab_lock_xy[0] = init_grab_xy[0];
|
||||
seat->grab_lock_xy[1] = init_grab_xy[1];
|
||||
}
|
||||
|
|
|
@ -47,6 +47,26 @@ void ghost_wl_surface_tag_cursor_pointer(struct wl_surface *surface);
|
|||
bool ghost_wl_surface_own_cursor_tablet(const struct wl_surface *surface);
|
||||
void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *surface);
|
||||
|
||||
/* Scaling to: translates from WAYLAND into GHOST (viewport local) coordinates.
|
||||
* Scaling from: performs the reverse translation.
|
||||
*
|
||||
* Scaling "to" is used to map WAYLAND location cursor coordinates to GHOST coordinates.
|
||||
* Scaling "from" is used to clamp cursor coordinates in WAYLAND local coordinates. */
|
||||
|
||||
struct GWL_WindowScaleParams;
|
||||
wl_fixed_t gwl_window_scale_wl_fixed_to(const GWL_WindowScaleParams &scale_params,
|
||||
wl_fixed_t value);
|
||||
wl_fixed_t gwl_window_scale_wl_fixed_from(const GWL_WindowScaleParams &scale_params,
|
||||
wl_fixed_t value);
|
||||
|
||||
/* Avoid this where possible as scaling integers often incurs rounding errors.
|
||||
* Scale #wl_fixed_t where possible.
|
||||
*
|
||||
* In general scale by large values where this is less likely to be a problem. */
|
||||
|
||||
int gwl_window_scale_int_to(const GWL_WindowScaleParams &scale_params, int value);
|
||||
int gwl_window_scale_int_from(const GWL_WindowScaleParams &scale_params, int value);
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
|
||||
/**
|
||||
* Return true when all required WAYLAND libraries are present,
|
||||
|
@ -181,6 +201,10 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_manager();
|
||||
struct xdg_activation_v1 *xdg_activation_manager();
|
||||
struct zwp_pointer_gestures_v1 *wp_pointer_gestures();
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager();
|
||||
struct wp_viewporter *wp_viewporter();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
libdecor *libdecor_context();
|
||||
|
@ -234,7 +258,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
const GHOST_Rect *wrap_bounds,
|
||||
GHOST_TAxisFlag wrap_axis,
|
||||
wl_surface *wl_surface,
|
||||
int scale);
|
||||
const struct GWL_WindowScaleParams &scale_params);
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
static bool use_libdecor_runtime();
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include <xdg-activation-v1-client-protocol.h>
|
||||
#include <xdg-decoration-unstable-v1-client-protocol.h>
|
||||
#include <xdg-shell-client-protocol.h>
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
# include <fractional-scale-v1-client-protocol.h>
|
||||
# include <viewporter-client-protocol.h>
|
||||
# define FRACTIONAL_DENOMINATOR 120
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
|
||||
|
@ -83,15 +88,92 @@ static void gwl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor)
|
|||
delete decor;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Window-Viewport/Wayland to/from Scale Conversion
|
||||
* \{ */
|
||||
|
||||
struct GWL_WindowScaleParams {
|
||||
bool is_fractional = false;
|
||||
/**
|
||||
* When fractional:
|
||||
* Scale is multiplied by #FRACTIONAL_DENOMINATOR.
|
||||
* Otherwise scale is an integer.
|
||||
*/
|
||||
wl_fixed_t scale = 0;
|
||||
};
|
||||
|
||||
wl_fixed_t gwl_window_scale_wl_fixed_to(const GWL_WindowScaleParams &scale_params,
|
||||
wl_fixed_t value)
|
||||
{
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (scale_params.is_fractional) {
|
||||
return (value * scale_params.scale) / FRACTIONAL_DENOMINATOR;
|
||||
}
|
||||
#endif
|
||||
return value * scale_params.scale;
|
||||
}
|
||||
wl_fixed_t gwl_window_scale_wl_fixed_from(const GWL_WindowScaleParams &scale_params,
|
||||
wl_fixed_t value)
|
||||
{
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (scale_params.is_fractional) {
|
||||
return (value * FRACTIONAL_DENOMINATOR) / scale_params.scale;
|
||||
}
|
||||
#endif
|
||||
return value / scale_params.scale;
|
||||
}
|
||||
|
||||
int gwl_window_scale_int_to(const GWL_WindowScaleParams &scale_params, int value)
|
||||
{
|
||||
return wl_fixed_to_int(gwl_window_scale_wl_fixed_to(scale_params, wl_fixed_from_int(value)));
|
||||
}
|
||||
int gwl_window_scale_int_from(const GWL_WindowScaleParams &scale_params, int value)
|
||||
{
|
||||
return wl_fixed_to_int(gwl_window_scale_wl_fixed_from(scale_params, wl_fixed_from_int(value)));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal #GWL_Window
|
||||
* \{ */
|
||||
|
||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||
|
||||
enum eGWL_PendingWindowActions {
|
||||
/**
|
||||
* The state of the window frame has changed, apply the state from #GWL_Window::frame_pending.
|
||||
*/
|
||||
PENDING_WINDOW_FRAME_CONFIGURE = 0,
|
||||
/** The EGL buffer must be resized to match #GWL_WindowFrame::size. */
|
||||
PENDING_EGL_WINDOW_RESIZE,
|
||||
# ifdef GHOST_OPENGL_ALPHA
|
||||
/** Draw an opaque region behind the window. */
|
||||
PENDING_OPAQUE_SET,
|
||||
# endif
|
||||
/**
|
||||
* The DPI for a monitor has changed or the monitors (outputs)
|
||||
* this window is visible on may have changed. Recalculate the windows scale.
|
||||
*/
|
||||
PENDING_OUTPUT_SCALE_UPDATE,
|
||||
};
|
||||
# define PENDING_NUM (PENDING_OUTPUT_SCALE_UPDATE + 1)
|
||||
|
||||
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
||||
|
||||
struct GWL_WindowFrame {
|
||||
/**
|
||||
* The frame size (in GHOST window coordinates).
|
||||
*
|
||||
* These must be converted to WAYLADN relative coordinates when the window is scaled
|
||||
* by Hi-DPI/fractional scaling.
|
||||
*/
|
||||
int32_t size[2] = {0, 0};
|
||||
bool is_maximised = false;
|
||||
bool is_fullscreen = false;
|
||||
bool is_active = false;
|
||||
/** Disable when the fractional scale is a whole number. */
|
||||
int fractional_scale = 0;
|
||||
};
|
||||
|
||||
struct GWL_Window {
|
||||
|
@ -109,14 +191,20 @@ struct GWL_Window {
|
|||
/** The scale value written to #wl_surface_set_buffer_scale. */
|
||||
int scale = 0;
|
||||
/**
|
||||
* The fractional scale used to calculate the DPI.
|
||||
* (always set, even when scaling is rounded to whole units).
|
||||
* The scale value to be used in the case fractional scale is disable.
|
||||
* In general this should only be used when changing states
|
||||
* (when disabling fractional scale).
|
||||
*/
|
||||
wl_fixed_t scale_fractional = 0;
|
||||
int scale_on_output = 0;
|
||||
|
||||
/** A temporary token used for the window to be notified of it's activation. */
|
||||
struct xdg_activation_token_v1 *xdg_activation_token = nullptr;
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
struct wp_viewport *viewport = nullptr;
|
||||
struct wp_fractional_scale_v1 *fractional_scale_handle = nullptr;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
WGL_LibDecor_Window *libdecor = nullptr;
|
||||
#endif
|
||||
|
@ -143,12 +231,15 @@ struct GWL_Window {
|
|||
|
||||
bool is_dialog = false;
|
||||
|
||||
/** Currently only initialized on access (avoids allocations & allows to keep private). */
|
||||
GWL_WindowScaleParams scale_params;
|
||||
|
||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||
/**
|
||||
* These pending actions can't be performed when WAYLAND handlers are running from a thread.
|
||||
* Postpone their execution until the main thread can handle them.
|
||||
*/
|
||||
std::atomic<bool> pending_actions[3];
|
||||
std::atomic<bool> pending_actions[PENDING_NUM];
|
||||
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
||||
};
|
||||
|
||||
|
@ -287,6 +378,124 @@ static bool gwl_window_state_set(GWL_Window *win, const GHOST_TWindowState state
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal #GWL_Window Viewport Setup/Teardown
|
||||
*
|
||||
* A viewport is needed to implement fractional scale,
|
||||
* as the outputs scale may change at runtime, support creating & clearing the viewport as needed.
|
||||
* \{ */
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
|
||||
/**
|
||||
* Scale a value from a viewport value to Wayland windowing.
|
||||
* Scale down or not at all.
|
||||
*/
|
||||
static int gwl_window_fractional_to_viewport(const GWL_WindowFrame &frame, int value)
|
||||
{
|
||||
GHOST_ASSERT(frame.fractional_scale != 0, "Not fractional or called before initiazlized!");
|
||||
return (value * frame.fractional_scale) / FRACTIONAL_DENOMINATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale a value from a Wayland windowing value to the viewport.
|
||||
* Scales up or not at all.
|
||||
*/
|
||||
static int gwl_window_fractional_from_viewport(const GWL_WindowFrame &frame, int value)
|
||||
{
|
||||
GHOST_ASSERT(frame.fractional_scale != 0, "Not fractional or called before initiazlized!");
|
||||
return (value * FRACTIONAL_DENOMINATOR) / frame.fractional_scale;
|
||||
}
|
||||
|
||||
/* NOTE: rounded versions are needed for window-frame dimensions conversions.
|
||||
* (rounding is part of the WAYLAND spec). All other conversions such as cursor coordinates
|
||||
* can used simple integer division as rounding is not defined in this case. */
|
||||
|
||||
static int gwl_window_fractional_to_viewport_round(const GWL_WindowFrame &frame, int value)
|
||||
{
|
||||
GHOST_ASSERT(frame.fractional_scale != 0, "Not fractional or called before initiazlized!");
|
||||
return lroundf(double(value * frame.fractional_scale) / double(FRACTIONAL_DENOMINATOR));
|
||||
}
|
||||
|
||||
static int gwl_window_fractional_from_viewport_round(const GWL_WindowFrame &frame, int value)
|
||||
{
|
||||
GHOST_ASSERT(frame.fractional_scale != 0, "Not fractional or called before initiazlized!");
|
||||
return lroundf(double(value * FRACTIONAL_DENOMINATOR) / double(frame.fractional_scale));
|
||||
}
|
||||
|
||||
static bool gwl_window_viewport_set(GWL_Window *win, bool *r_surface_needs_commit)
|
||||
{
|
||||
if (win->viewport != nullptr) {
|
||||
return false;
|
||||
}
|
||||
struct wp_viewporter *viewporter = win->ghost_system->wp_viewporter();
|
||||
if (viewporter == nullptr) {
|
||||
return false;
|
||||
}
|
||||
win->viewport = wp_viewporter_get_viewport(viewporter, win->wl_surface);
|
||||
if (win->viewport == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set the buffer scale to 1 since a viewport will be used. */
|
||||
if (win->scale != 1) {
|
||||
win->scale = 1;
|
||||
wl_surface_set_buffer_scale(win->wl_surface, win->scale);
|
||||
if (r_surface_needs_commit) {
|
||||
*r_surface_needs_commit = true;
|
||||
}
|
||||
else {
|
||||
wl_surface_commit(win->wl_surface);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gwl_window_viewport_unset(GWL_Window *win, bool *r_surface_needs_commit)
|
||||
{
|
||||
if (win->viewport == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wp_viewport_destroy(win->viewport);
|
||||
win->viewport = nullptr;
|
||||
|
||||
GHOST_ASSERT(win->scale == 1, "Unexpected scale!");
|
||||
if (win->scale != win->scale_on_output) {
|
||||
win->scale = win->scale_on_output;
|
||||
wl_surface_set_buffer_scale(win->wl_surface, win->scale);
|
||||
if (r_surface_needs_commit) {
|
||||
*r_surface_needs_commit = true;
|
||||
}
|
||||
else {
|
||||
wl_surface_commit(win->wl_surface);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gwl_window_viewport_size_update(GWL_Window *win)
|
||||
{
|
||||
if (win->viewport == nullptr) {
|
||||
return false;
|
||||
}
|
||||
wp_viewport_set_source(win->viewport,
|
||||
wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(0),
|
||||
wl_fixed_from_int(win->frame.size[0]),
|
||||
wl_fixed_from_int(win->frame.size[1]));
|
||||
wp_viewport_set_destination(
|
||||
win->viewport,
|
||||
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[0]),
|
||||
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[1]));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal #GWL_Window Activation
|
||||
* \{ */
|
||||
|
@ -346,7 +555,26 @@ static void gwl_window_activate(GWL_Window *win)
|
|||
/** \name Internal #GWL_Window Pending Actions
|
||||
* \{ */
|
||||
|
||||
static void gwl_window_frame_pending_size_set(GWL_Window *win)
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win,
|
||||
bool *r_surface_needs_commit)
|
||||
{
|
||||
if (win->frame_pending.fractional_scale == win->frame.fractional_scale) {
|
||||
return;
|
||||
}
|
||||
|
||||
win->frame.fractional_scale = win->frame_pending.fractional_scale;
|
||||
if (win->frame_pending.fractional_scale) {
|
||||
gwl_window_viewport_set(win, r_surface_needs_commit);
|
||||
gwl_window_viewport_size_update(win);
|
||||
}
|
||||
else {
|
||||
gwl_window_viewport_unset(win, r_surface_needs_commit);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
static void gwl_window_frame_pending_size_set(GWL_Window *win, bool *r_surface_needs_commit)
|
||||
{
|
||||
if (win->frame_pending.size[0] == 0 || win->frame_pending.size[1] == 0) {
|
||||
return;
|
||||
|
@ -355,7 +583,19 @@ static void gwl_window_frame_pending_size_set(GWL_Window *win)
|
|||
win->frame.size[0] = win->frame_pending.size[0];
|
||||
win->frame.size[1] = win->frame_pending.size[1];
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (win->frame_pending.fractional_scale != win->frame.fractional_scale) {
|
||||
gwl_window_frame_pending_fractional_scale_set(win, r_surface_needs_commit);
|
||||
}
|
||||
else {
|
||||
gwl_window_viewport_size_update(win);
|
||||
}
|
||||
#else
|
||||
(void)r_surface_needs_commit;
|
||||
#endif
|
||||
|
||||
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
|
||||
|
||||
win->ghost_window->notify_size();
|
||||
|
||||
win->frame_pending.size[0] = 0;
|
||||
|
@ -366,25 +606,6 @@ static void gwl_window_frame_update_from_pending(GWL_Window *win);
|
|||
|
||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||
|
||||
enum eGWL_PendingWindowActions {
|
||||
/**
|
||||
* The state of the window frame has changed, apply the state from #GWL_Window::frame_pending.
|
||||
*/
|
||||
PENDING_WINDOW_FRAME_CONFIGURE = 0,
|
||||
/** The EGL buffer must be resized to match #GWL_WindowFrame::size. */
|
||||
PENDING_EGL_WINDOW_RESIZE,
|
||||
# ifdef GHOST_OPENGL_ALPHA
|
||||
/** Draw an opaque region behind the window. */
|
||||
PENDING_OPAQUE_SET,
|
||||
# endif
|
||||
/**
|
||||
* The DPI for a monitor has changed or the monitors (outputs)
|
||||
* this window is visible on may have changed. Recalculate the windows scale.
|
||||
*/
|
||||
PENDING_OUTPUT_SCALE_UPDATE,
|
||||
};
|
||||
# define PENDING_NUM (PENDING_OUTPUT_SCALE_UPDATE + 1)
|
||||
|
||||
static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWindowActions type)
|
||||
{
|
||||
win->pending_actions[int(type)].store(true);
|
||||
|
@ -397,6 +618,9 @@ static void gwl_window_pending_actions_handle(GWL_Window *win)
|
|||
gwl_window_frame_update_from_pending(win);
|
||||
}
|
||||
if (win->pending_actions[PENDING_EGL_WINDOW_RESIZE].exchange(false)) {
|
||||
# ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
gwl_window_viewport_size_update(win);
|
||||
# endif
|
||||
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
|
||||
}
|
||||
# ifdef GHOST_OPENGL_ALPHA
|
||||
|
@ -423,13 +647,32 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
|
|||
|
||||
#endif
|
||||
|
||||
const bool dpi_changed = win->frame_pending.fractional_scale != win->frame.fractional_scale;
|
||||
bool surface_needs_commit = false;
|
||||
|
||||
if (win->frame_pending.size[0] != 0 && win->frame_pending.size[1] != 0) {
|
||||
if ((win->frame.size[0] != win->frame_pending.size[0]) ||
|
||||
(win->frame.size[1] != win->frame_pending.size[1])) {
|
||||
gwl_window_frame_pending_size_set(win);
|
||||
gwl_window_frame_pending_size_set(win, &surface_needs_commit);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (win->frame_pending.fractional_scale != win->frame.fractional_scale) {
|
||||
gwl_window_frame_pending_fractional_scale_set(win, &surface_needs_commit);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (surface_needs_commit) {
|
||||
wl_surface_commit(win->wl_surface);
|
||||
}
|
||||
|
||||
if (dpi_changed) {
|
||||
GHOST_SystemWayland *system = win->ghost_system;
|
||||
system->pushEvent(new GHOST_Event(
|
||||
system->getMilliSeconds(), GHOST_kEventWindowDPIHintChanged, win->ghost_window));
|
||||
}
|
||||
|
||||
if (win->frame_pending.is_active) {
|
||||
win->ghost_window->activate();
|
||||
}
|
||||
|
@ -472,26 +715,11 @@ static int output_scale_cmp(const GWL_Output *output_a, const GWL_Output *output
|
|||
if (output_a->scale > output_b->scale) {
|
||||
return 1;
|
||||
}
|
||||
if (output_a->has_scale_fractional || output_b->has_scale_fractional) {
|
||||
const wl_fixed_t scale_fractional_a = output_a->has_scale_fractional ?
|
||||
output_a->scale_fractional :
|
||||
wl_fixed_from_int(output_a->scale);
|
||||
const wl_fixed_t scale_fractional_b = output_b->has_scale_fractional ?
|
||||
output_b->scale_fractional :
|
||||
wl_fixed_from_int(output_b->scale);
|
||||
if (scale_fractional_a < scale_fractional_b) {
|
||||
return -1;
|
||||
}
|
||||
if (scale_fractional_a > scale_fractional_b) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int outputs_max_scale_or_default(const std::vector<GWL_Output *> &outputs,
|
||||
const int32_t scale_default,
|
||||
wl_fixed_t *r_scale_fractional)
|
||||
const int32_t scale_default)
|
||||
{
|
||||
const GWL_Output *output_max = nullptr;
|
||||
for (const GWL_Output *reg_output : outputs) {
|
||||
|
@ -501,17 +729,9 @@ static int outputs_max_scale_or_default(const std::vector<GWL_Output *> &outputs
|
|||
}
|
||||
|
||||
if (output_max) {
|
||||
if (r_scale_fractional) {
|
||||
*r_scale_fractional = output_max->has_scale_fractional ?
|
||||
output_max->scale_fractional :
|
||||
wl_fixed_from_int(output_max->scale);
|
||||
}
|
||||
return output_max->scale;
|
||||
}
|
||||
|
||||
if (r_scale_fractional) {
|
||||
*r_scale_fractional = wl_fixed_from_int(scale_default);
|
||||
}
|
||||
return scale_default;
|
||||
}
|
||||
|
||||
|
@ -539,8 +759,17 @@ static void xdg_toplevel_handle_configure(void *data,
|
|||
std::lock_guard lock_frame_guard{win->frame_pending_mutex};
|
||||
#endif
|
||||
|
||||
win->frame_pending.size[0] = win->scale * width;
|
||||
win->frame_pending.size[1] = win->scale * height;
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (win->frame.fractional_scale) {
|
||||
win->frame_pending.size[0] = gwl_window_fractional_to_viewport_round(win->frame, width);
|
||||
win->frame_pending.size[1] = gwl_window_fractional_to_viewport_round(win->frame, height);
|
||||
}
|
||||
else
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
{
|
||||
win->frame_pending.size[0] = width * win->scale;
|
||||
win->frame_pending.size[1] = height * win->scale;
|
||||
}
|
||||
|
||||
win->frame_pending.is_maximised = false;
|
||||
win->frame_pending.is_fullscreen = false;
|
||||
|
@ -615,6 +844,63 @@ static const struct xdg_activation_token_v1_listener *xdg_activation_listener_ge
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Listener (Fractional Scale), #wp_fractional_scale_manager_v1_interface
|
||||
*
|
||||
* Used by #gwl_window_activate.
|
||||
* \{ */
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
|
||||
static CLG_LogRef LOG_WL_FRACTIONAL_SCALE = {"ghost.wl.handle.fractional_scale"};
|
||||
# define LOG (&LOG_WL_FRACTIONAL_SCALE)
|
||||
|
||||
static void wp_fractional_scale_handle_preferred_scale(
|
||||
void *data, struct wp_fractional_scale_v1 * /*wp_fractional_scale_v1*/, uint preferred_scale)
|
||||
{
|
||||
CLOG_INFO(LOG,
|
||||
2,
|
||||
"preferred_scale (preferred_scale=%.6f)",
|
||||
double(preferred_scale) / FRACTIONAL_DENOMINATOR);
|
||||
GWL_Window *win = static_cast<GWL_Window *>(data);
|
||||
const bool is_fractional = (preferred_scale % FRACTIONAL_DENOMINATOR) != 0;
|
||||
/* When non-fractional, never use fractional scaling! */
|
||||
win->frame_pending.fractional_scale = is_fractional ? preferred_scale : 0;
|
||||
|
||||
if (win->frame.fractional_scale != win->frame_pending.fractional_scale) {
|
||||
|
||||
/* Resize the window failing to do so results in severe flickering with a
|
||||
* multi-monitor setup when multiple monitors have different scales.
|
||||
*
|
||||
* NOTE: some flickering is still possible even when resizing this
|
||||
* happens when dragging the right hand side of the title-bar in KDE
|
||||
* as expanding changed the size on the RHS, this may be up to the compositor to fix. */
|
||||
const int scale_prev = win->frame.fractional_scale ?
|
||||
win->frame.fractional_scale :
|
||||
win->scale_on_output * FRACTIONAL_DENOMINATOR;
|
||||
const int scale_next = win->frame_pending.fractional_scale ?
|
||||
win->frame_pending.fractional_scale :
|
||||
win->scale_on_output * FRACTIONAL_DENOMINATOR;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(win->frame_pending.size); i++) {
|
||||
const int value = win->frame_pending.size[i] ? win->frame_pending.size[i] :
|
||||
win->frame.size[i];
|
||||
win->frame_pending.size[i] = lroundf(value * (double(scale_next) / double(scale_prev)));
|
||||
}
|
||||
|
||||
gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = {
|
||||
/*preferred_scale*/ wp_fractional_scale_handle_preferred_scale,
|
||||
};
|
||||
|
||||
# undef LOG
|
||||
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Listener (LibDecor Frame), #libdecor_frame_interface
|
||||
* \{ */
|
||||
|
@ -639,16 +925,27 @@ static void frame_handle_configure(struct libdecor_frame *frame,
|
|||
/* Set the size. */
|
||||
int size_next[2];
|
||||
{
|
||||
const int scale = static_cast<GWL_Window *>(data)->scale;
|
||||
GWL_Window *win = static_cast<GWL_Window *>(data);
|
||||
const int scale = win->scale;
|
||||
if (!libdecor_configuration_get_content_size(
|
||||
configuration, frame, &size_next[0], &size_next[1])) {
|
||||
GWL_Window *win = static_cast<GWL_Window *>(data);
|
||||
size_next[0] = win->frame.size[0] / scale;
|
||||
size_next[1] = win->frame.size[1] / scale;
|
||||
}
|
||||
|
||||
frame_pending->size[0] = scale * size_next[0];
|
||||
frame_pending->size[1] = scale * size_next[1];
|
||||
# ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (win->frame.fractional_scale) {
|
||||
win->frame_pending.size[0] = gwl_window_fractional_to_viewport_round(win->frame,
|
||||
size_next[0]);
|
||||
win->frame_pending.size[1] = gwl_window_fractional_to_viewport_round(win->frame,
|
||||
size_next[1]);
|
||||
}
|
||||
else
|
||||
# endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
{
|
||||
frame_pending->size[0] = size_next[0] * scale;
|
||||
frame_pending->size[1] = size_next[1] * scale;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the state. */
|
||||
|
@ -888,7 +1185,8 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
|||
*
|
||||
* Using the maximum scale is best as it results in the window first being smaller,
|
||||
* avoiding a large window flashing before it's made smaller. */
|
||||
window_->scale = outputs_max_scale_or_default(system_->outputs(), 1, &window_->scale_fractional);
|
||||
window_->scale = outputs_max_scale_or_default(system_->outputs(), 1);
|
||||
window_->scale_on_output = window_->scale;
|
||||
|
||||
window_->frame.size[0] = int32_t(width);
|
||||
window_->frame.size[1] = int32_t(height);
|
||||
|
@ -911,6 +1209,17 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
|||
window_->egl_window = wl_egl_window_create(
|
||||
window_->wl_surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
struct wp_fractional_scale_manager_v1 *fractional_scale_manager =
|
||||
system->wp_fractional_scale_manager();
|
||||
if (fractional_scale_manager) {
|
||||
window_->fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale(
|
||||
fractional_scale_manager, window_->wl_surface);
|
||||
wp_fractional_scale_v1_add_listener(
|
||||
window_->fractional_scale_handle, &wp_fractional_scale_listener, window_);
|
||||
}
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
/* NOTE: The limit is in points (not pixels) so Hi-DPI will limit to larger number of pixels.
|
||||
* This has the advantage that the size limit is the same when moving the window between monitors
|
||||
* with different scales set. If it was important to limit in pixels it could be re-calculated
|
||||
|
@ -1029,13 +1338,14 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mo
|
|||
}
|
||||
bounds = &bounds_buf;
|
||||
}
|
||||
|
||||
if (system_->window_cursor_grab_set(mode,
|
||||
m_cursorGrab,
|
||||
m_cursorGrabInitPos,
|
||||
bounds,
|
||||
m_cursorGrabAxis,
|
||||
window_->wl_surface,
|
||||
window_->scale)) {
|
||||
this->scale_params())) {
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
return GHOST_kFailure;
|
||||
|
@ -1121,7 +1431,7 @@ GHOST_TSuccess GHOST_WindowWayland::setClientSize(const uint32_t width, const ui
|
|||
window_->frame_pending.size[0] = width;
|
||||
window_->frame_pending.size[1] = height;
|
||||
|
||||
gwl_window_frame_pending_size_set(window_);
|
||||
gwl_window_frame_pending_size_set(window_, nullptr);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
@ -1159,6 +1469,18 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
|
|||
window_->xdg_activation_token = nullptr;
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (window_->fractional_scale_handle) {
|
||||
wp_fractional_scale_v1_destroy(window_->fractional_scale_handle);
|
||||
window_->fractional_scale_handle = nullptr;
|
||||
}
|
||||
|
||||
if (window_->viewport) {
|
||||
wp_viewport_destroy(window_->viewport);
|
||||
window_->viewport = nullptr;
|
||||
}
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
if (use_libdecor) {
|
||||
gwl_libdecor_window_destroy(window_->libdecor);
|
||||
|
@ -1188,25 +1510,13 @@ uint16_t GHOST_WindowWayland::getDPIHint()
|
|||
/* No need to lock `server_mutex`
|
||||
* (`outputs_changed_update_scale` never changes values in a non-main thread). */
|
||||
|
||||
const wl_fixed_t scale_fractional = window_->scale_fractional;
|
||||
GHOST_ASSERT(wl_fixed_from_int(window_->scale) >= scale_fractional,
|
||||
"Fractional scale should always be less than the fixed scale.");
|
||||
|
||||
/* Using the physical DPI will cause wrong scaling of the UI
|
||||
* use a multiplier for the default DPI as a workaround. */
|
||||
if (wl_fixed_from_int(window_->scale) == scale_fractional || window_->scale <= 1) {
|
||||
/* No fractional scaling. */
|
||||
return window_->scale * base_dpi;
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (window_->frame.fractional_scale) {
|
||||
return gwl_window_fractional_to_viewport(window_->frame, base_dpi);
|
||||
}
|
||||
const int scale_ceil = window_->scale;
|
||||
const int scale_floor = scale_ceil - 1;
|
||||
const wl_fixed_t scale_fractional_final = wl_fixed_to_int(
|
||||
scale_fractional *
|
||||
/* Compensate for the buffer being rendered at `window_->scale`,
|
||||
* then scaled down fractionally. */
|
||||
(wl_fixed_from_int(1) + ((wl_fixed_from_int(scale_ceil) - scale_fractional) / scale_floor)));
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
return wl_fixed_to_int(scale_fractional_final * base_dpi);
|
||||
return window_->scale * base_dpi;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWayland::setWindowCursorVisibility(bool visible)
|
||||
|
@ -1379,9 +1689,35 @@ int GHOST_WindowWayland::scale() const
|
|||
return window_->scale;
|
||||
}
|
||||
|
||||
wl_fixed_t GHOST_WindowWayland::scale_fractional() const
|
||||
const struct GWL_WindowScaleParams &GHOST_WindowWayland::scale_params() const
|
||||
{
|
||||
return window_->scale_fractional;
|
||||
/* NOTE(@ideasman42): This could be kept initialized,
|
||||
* since it's such a small struct it's not so important. */
|
||||
GWL_WindowScaleParams *scale_params = &window_->scale_params;
|
||||
scale_params->is_fractional = (window_->frame.fractional_scale != 0);
|
||||
scale_params->scale = scale_params->is_fractional ? window_->frame.fractional_scale :
|
||||
window_->scale;
|
||||
return *scale_params;
|
||||
}
|
||||
|
||||
wl_fixed_t GHOST_WindowWayland::wl_fixed_from_window(wl_fixed_t value) const
|
||||
{
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (window_->frame.fractional_scale) {
|
||||
return gwl_window_fractional_from_viewport(window_->frame, value);
|
||||
}
|
||||
#endif
|
||||
return value / window_->scale;
|
||||
}
|
||||
|
||||
wl_fixed_t GHOST_WindowWayland::wl_fixed_to_window(wl_fixed_t value) const
|
||||
{
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (window_->frame.fractional_scale) {
|
||||
return gwl_window_fractional_to_viewport(window_->frame, value);
|
||||
}
|
||||
#endif
|
||||
return value * window_->scale;
|
||||
}
|
||||
|
||||
wl_surface *GHOST_WindowWayland::wl_surface() const
|
||||
|
@ -1499,13 +1835,19 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
|
|||
}
|
||||
#endif
|
||||
|
||||
wl_fixed_t scale_fractional_next = 0;
|
||||
const int scale_next = outputs_max_scale_or_default(outputs(), 0, &scale_fractional_next);
|
||||
const int scale_next = outputs_max_scale_or_default(outputs(), 0);
|
||||
if (UNLIKELY(scale_next == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const wl_fixed_t scale_fractional_curr = window_->scale_fractional;
|
||||
#ifdef WITH_GHOST_WAYLAND_FRACTIONAL_SCALE
|
||||
if (window_->frame.fractional_scale) {
|
||||
GHOST_ASSERT(window_->scale == 1, "Scale is expected to be 1 for fractional scaling!");
|
||||
window_->scale_on_output = scale_next;
|
||||
return false;
|
||||
}
|
||||
#endif /* WITH_GHOST_WAYLAND_FRACTIONAL_SCALE */
|
||||
|
||||
const int scale_curr = window_->scale;
|
||||
bool changed = false;
|
||||
|
||||
|
@ -1530,22 +1872,18 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
|
|||
window_->frame_pending.size[0] = (window_->frame.size[0] / scale_curr) * scale_next;
|
||||
window_->frame_pending.size[1] = (window_->frame.size[1] / scale_curr) * scale_next;
|
||||
|
||||
gwl_window_frame_pending_size_set(window_);
|
||||
gwl_window_frame_pending_size_set(window_, nullptr);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (scale_fractional_next != scale_fractional_curr) {
|
||||
window_->scale_fractional = scale_fractional_next;
|
||||
changed = true;
|
||||
|
||||
/* As this is a low-level function, we might want adding this event to be optional,
|
||||
* always add the event unless it causes issues. */
|
||||
GHOST_SystemWayland *system = window_->ghost_system;
|
||||
system->pushEvent(
|
||||
new GHOST_Event(system->getMilliSeconds(), GHOST_kEventWindowDPIHintChanged, this));
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
/* Ensure both are always set. */
|
||||
window_->scale_on_output = window_->scale;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,10 +140,14 @@ class GHOST_WindowWayland : public GHOST_Window {
|
|||
/* WAYLAND direct-data access. */
|
||||
|
||||
int scale() const;
|
||||
wl_fixed_t scale_fractional() const;
|
||||
const struct GWL_WindowScaleParams &scale_params() const;
|
||||
|
||||
struct wl_surface *wl_surface() const;
|
||||
const std::vector<GWL_Output *> &outputs();
|
||||
|
||||
wl_fixed_t wl_fixed_from_window(wl_fixed_t value) const;
|
||||
wl_fixed_t wl_fixed_to_window(wl_fixed_t value) const;
|
||||
|
||||
/* WAYLAND window-level functions. */
|
||||
|
||||
GHOST_TSuccess close();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
if(HAVE_MALLOC_STATS_H)
|
||||
add_definitions(-DHAVE_MALLOC_STATS_H)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2013 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2013 Blender Foundation */
|
||||
|
||||
/** \file
|
||||
* \ingroup intern_mem
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
|
||||
set(INC
|
||||
intern
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
# Copyright 2006 Blender Foundation
|
||||
remove_strict_flags()
|
||||
set(INC
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2015 Blender Foundation. All rights reserved.
|
||||
# Copyright 2015 Blender Foundation
|
||||
|
||||
set(INC
|
||||
.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2020 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2020 Blender Foundation */
|
||||
|
||||
/* On Linux, precompiled libraries may be made with an glibc version that is
|
||||
* incompatible with the system libraries that Blender is built on. To solve
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2011 Blender Foundation. All rights reserved.
|
||||
# Copyright 2011 Blender Foundation
|
||||
|
||||
# NOTE: This file is automatically generated by bundle.sh script
|
||||
# If you're doing changes in this file, please update template
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
#include "intern/autotrack.h"
|
||||
#include "intern/tracksN.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2014 Blender Foundation. All rights reserved. */
|
||||
* Copyright 2014 Blender Foundation */
|
||||
|
||||
#ifndef LIBMV_C_API_AUTOTRACK_H_
|
||||
#define LIBMV_C_API_AUTOTRACK_H_
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue