Compare commits

...

42 Commits

Author SHA1 Message Date
Vitaly Provodin
b276934ea7 fixup! JBR-6181 add Linux executables with bundled FreeType 2023-10-15 17:30:34 +07:00
Vitaly Provodin
0861698478 JBR-6181 add Linux executables with bundled FreeType 2023-10-13 06:53:18 +04:00
Alexey Ushakov
054df02388 JBR-4983 MacOS Ventura - External monitor lagging
Added extra redraw request
Enabled the fix by default only for M2 and spans displays property enabled (Displays have separate spaces OFF)
2023-10-10 13:56:26 +02:00
Maxim Kartashev
e4d4fa74d2 JBR-6142 Impossible to move/resize IDE window after restart if several projects were initially opened on secondary monitor
Announce to Mutter that we are "client-decorated" when a Frame is
undecorated by setting _GTK_FRAME_EXTENTS to all zeroes.
This prevents Mutter from applying certain harmful heuristics.
2023-10-10 15:31:47 +04:00
Maxim Kartashev
8d1d4351b9 JBR-6183 Wayland: clipboard-related exception in headless environment 2023-10-10 11:43:03 +04:00
Dmitrii Morskii
246e3a3de9 JBR-6135 removed dependence on process reading TTF in fixed size chunks 2023-10-09 15:01:15 +02:00
bourgesl
1b65d2d228 JBR-6119: RenderPerf enhancements:
new executor modes (buffer & volatile), robot calibration & more statistics and CLI arguments
added version + help information, added time unit

(cherry picked from commit 2afc66470aa3d3a77ab590b9e0eb4c799be432be)
2023-10-04 20:58:39 +02:00
Alexey Ushakov
474629f98a JBR-6132 Crash in [MTLLayer blitTexture] when MTL_DEBUG_LAYER enabled
Blit operation should not be performed on textures with MTLTextureUsageRenderTarget only, so changing framebufferOnly to NO
2023-10-04 16:12:47 +02:00
Nikita Gubarkov
76c483eec1 JBR-6144 Build JBR with Vulkan support
1. Update dockerfile to checkout Vulkan headers
2. Fix --with-vulkan-include configure option
2023-10-04 14:53:17 +02:00
Alexey Ushakov
7685c6b5f9 JBR-6158 Cannot build jbr21 with wayland toolkit on wsl2
Added --with-wayland-lib option to provide custom library path
2023-10-03 19:59:01 +02:00
Maxim Kartashev
6a1c5bd43a JBR-5857 Wayland: implement clipboard support 2023-10-02 19:38:31 +04:00
Dmitry Batrak
5e738482b1 JBR-6145 [Wayland toolkit] Popup windows aren't focusable
A partial solution. Cases not still covered:
* Alt+tab from the app and back should keep popup focused if it was focused initially
* Mouse clicks between popup and owner should transfer focus as expected
2023-09-29 20:14:01 +03:00
Vitaly Provodin
17556b0ea3 update exclude list on results of 21_b243.1 test runs 2023-09-29 15:47:08 +04:00
Vitaly Provodin
7dda83bf0b JBR-6130 add VK_TAB release action 2023-09-29 15:47:08 +04:00
Maxim Kartashev
ca1889e682 JBR-6138 Wayland: utilize gtk_shell1 protocol to mark dialogs as modal 2023-09-29 09:38:21 +04:00
Maxim Kartashev
258cf006bc JBR-6117 Wayland: JVM shutdown hang 2023-09-28 09:01:26 +04:00
Nikita Provotorov
a240282285 JBR-5984: IM's candidate window is placed under popup windows.
- Implements the optional method [NSTextInputClient windowLevel] to tell the macOS IM subsystem correct level of the window;
- Adds a regression test ImWindowIsPlacedUnderPopup5984.java.

(cherry picked from commit 5a91aae9c2)
2023-09-26 22:01:45 +02:00
Dmitrii Morskii
edfe753192 JBR-6044 handle absence of fontConfig library in setupRenderingFontHints 2023-09-25 12:51:03 +02:00
Dmitrii Morskii
7d8ca546f4 JBR-6041 started using correct type inside FcPatternGetValueFuncType 2023-09-25 12:50:59 +02:00
ghostflyby
b9d1c0e801 JBR-6124 Fix macOS services writing text back to textfield 2023-09-25 11:37:53 +02:00
Dmitry Batrak
d47223ddd9 JBR-5961 Wayland: can't switch between projects using menu
prevent using a pointer to destroyed surface
2023-09-25 09:33:15 +03:00
Vitaly Provodin
862b0d9195 update exclude list on results of 21_b240.22 test runs 2023-09-22 17:31:35 +07:00
Nikita Gubarkov
0457603fb6 JBR-6098 x64 docker images with glslc. 2023-09-21 10:21:40 +02:00
Sergey Shelomentsev
12c88c770d exclude FocusTraversalOrderTest 2023-09-20 21:34:29 +03:00
Sergey Shelomentsev
ac57aef98b JBR-6060 add focus traversal order test 2023-09-20 21:21:41 +03:00
Vitaly Provodin
40da69a5fb JBR-6070 update docker images for Alpine Linux 2023-09-16 08:35:57 +07:00
Vitaly Provodin
e4596e18e9 update exclude list on results of 21_b231.1 commit test runs 2023-09-16 08:35:57 +07:00
Dmitry Batrak
a24ed041aa JBR-5961 Wayland: can't switch between projects using menu
fix typo
2023-09-15 14:45:03 +03:00
Dmitry Batrak
d0bf4506c0 JBR-5961 Wayland: can't switch between projects using menu
support Window.toFront in Wayland toolkit
2023-09-15 12:44:26 +03:00
Maxim Kartashev
836f44fded JBR-6071 Alpine Linux compilation: error: implicit declaration of function 'pthread_getname_np' 2023-09-15 12:52:05 +04:00
Vitaly Provodin
f0bbcfc492 update exclude list on results of 21.231.1 test runs 2023-09-15 04:13:18 +07:00
Maxim Kartashev
e829d44cb9 JBR-5989 Wayland: jdk_awt_wayland test group 2023-09-13 08:26:46 +04:00
Maxim Kartashev
df095ab6db JBR-6025 Wayland: miscellaneous small improvements 2023-09-13 08:26:32 +04:00
Nikita Gubarkov
c301e17244 JBR-6016 doPrivileged for JBR API internal services.
(cherry picked from commit 19917e72086f091ef845959a29e7814ff6d88aa7)
2023-09-11 15:07:25 +02:00
Alexey Ushakov
f66a111d13 JBR-6045 WLToolkit(Vulkan): Add options to select physical device
Changed access to _name field, minor corrections in verbose print
2023-09-08 12:28:07 +02:00
Vitaly Provodin
6db1b3ec3c update exclude list on results of 21_b218.1 test runs 2023-09-08 17:06:59 +07:00
Alexey Ushakov
a19d03327a JBR-6045 WLToolkit(Vulkan): Add options to select physical device
Implemented -Dsun.java2d.vulkan=True and -Dsun.java2d.vulkan.deviceNumber=n VM options
2023-09-07 21:47:40 +02:00
Dmitrii Morskii
6d63ee0477 JBR-5502: optimize stringWidth & charsWidth methods of FontDesignMetrics 2023-09-07 17:23:55 +02:00
Dmitrii Morskii
60928807c8 JBR-6018 removed incorrect test testFeaturesZeroFrac 2023-09-07 14:51:20 +02:00
Maxim Kartashev
da11c5e526 JBR-6036 Wayland: Cannot invoke "java.awt.Component.getWidth()" because "popupParent" is null
Not all POPUP Window's have their parent set. And only those who do
shall be treated as popups in the Wayland's sense.
2023-09-06 19:23:07 +04:00
Nikita Tsarev
c56af99364 JBR-6028: Check before attempting to switch to a layout that might not exist in KeyCodesTest 2023-09-06 17:01:24 +02:00
Nikita Gubarkov
492fddd948 JBR-5973 Implement rendering of no-AA shapes with Vulkan pipeline
Get rid of maxTextureSize in Vulkan code. This concept was introduced to fix macOS-specific bugs and don't map well to Vulkan implementation, as this value is tied to specific device and texture format, so get rid of it for now and see whether we need it at all.

Refactored native surface data hierarchy. There was a C-style "inheritance" model with VKSDOps having an SurfaceDataOps as its first member and conversions back and forth between them. And then also privOps - pointer to the platform-specific part (WLVK). This was refactored into plain inheritance: SurfaceDataOps -> VKSurfaceData -> VKSwapchainSurfaceData -> WLVKSurfaceData

State management, synchronization & layout transition. Now using dynamic rendering and synchronization2 extensions.
Each device has a single timeline semaphore (basically 64-bit counter), monotonically increasing as device executes our commands, allowing us to track the state of the submitted batches and reuse resources which are no longer in use.

Split command recording into primary and secondary command buffers.
This allows us to record commands "in the past", before current render pass started, which gives possibility for some heavy optimizations:
1. When we suddenly need some texture in the middle of the render pass - no need to stop render pass in order to insert necessary synchronization - we can do it as if we knew it beforehand.
2. When we draw something and then clear the surface - just erase all commands inside current render pass we recorded earlier, so the actual drawing will never happen.

Shaders are compiled with glslc or glslangValidator and bytecode is inlined directly into libawt_wlawt

Memory management via VMA, vertex buffer pool, shader push constants.

Other refactoring.
2023-09-06 15:26:12 +02:00
92 changed files with 31427 additions and 1103 deletions

View File

@@ -8,15 +8,36 @@
FROM arm64v8/alpine:3.12
# Install the necessary build tools
RUN apk --no-cache add --update bash grep tar zip bzip2 rsync fontconfig build-base \
git libx11-dev libxext-dev libxrandr-dev libxrender-dev libxt-dev \
libxtst-dev autoconf freetype-dev cups-dev alsa-lib-dev file \
fontconfig fontconfig-dev linux-headers
RUN apk --no-cache add --update \
alsa-lib-dev=1.2.2-r0 \
autoconf=2.69-r2 \
bash=5.0.17-r0 \
build-base=0.5-r2 \
bzip2=1.0.8-r1 \
cups-dev=2.3.3-r0 \
file=5.38-r0 \
fontconfig=2.13.1-r2 \
fontconfig-dev=2.13.1-r2 \
freetype-dev=2.10.4-r2 \
git=2.26.3-r1 \
grep=3.4-r0 \
libx11-dev=1.6.12-r1 \
libxext-dev=1.3.4-r0 \
libxrandr-dev=1.5.2-r0 \
libxrender-dev=0.9.10-r3 \
libxt-dev=1.2.0-r0 \
libxtst-dev=1.2.3-r3 \
linux-headers=5.4.5-r1 \
rsync=3.1.3-r3 \
tar=1.32-r2 \
wayland-dev=1.18.0-r4 \
zip=3.0-r8
# Set up boot JDK for building
COPY boot_jdk_musl_aarch64.tar.gz /jdk17/
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk_musl_aarch64.tar.gz && rm /jdk17/boot_jdk_musl_aarch64.tar.gz
ENV BOOT_JDK=/jdk17
COPY boot_jdk_musl_aarch64.tar.gz /jdk20/
RUN cd /jdk20 && tar --strip-components=1 -xzf boot_jdk_musl_aarch64.tar.gz && rm /jdk20/boot_jdk_musl_aarch64.tar.gz
ENV BOOT_JDK=/jdk20
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -8,15 +8,35 @@
FROM alpine:3.14
# Install the necessary build tools
RUN apk --no-cache add --update bash grep tar zip bzip2 rsync fontconfig build-base \
git libx11-dev libxext-dev libxrandr-dev libxrender-dev libxt-dev \
libxtst-dev autoconf freetype-dev cups-dev alsa-lib-dev file \
fontconfig fontconfig-dev linux-headers
RUN apk --no-cache add --update \
alsa-lib-dev=1.2.5-r2 \
autoconf=2.71-r0 \
bash=5.1.16-r0 \
build-base=0.5-r3 \
bzip2=1.0.8-r1 \
cups-dev=2.3.3-r3 \
file=5.40-r1 \
fontconfig=2.13.1-r4 \
fontconfig-dev=2.13.1-r4 \
freetype-dev=2.10.4-r3 \
git=2.32.7-r0 \
grep=3.7-r0 \
libx11-dev=1.7.3.1-r0 \
libxext-dev=1.3.4-r0 \
libxrandr-dev=1.5.2-r1 \
libxrender-dev=0.9.10-r3 \
libxt-dev=1.2.1-r0 \
libxtst-dev=1.2.3-r3 \
linux-headers=5.10.41-r0 \
rsync=3.2.5-r0 \
tar=1.34-r1 \
wayland-dev=1.19.0-r0 \
zip=3.0-r9
# Set up boot JDK for building
COPY boot_jdk_musl_amd64.tar.gz /jdk17/
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk_musl_amd64.tar.gz && rm /jdk17/boot_jdk_musl_amd64.tar.gz
ENV BOOT_JDK=/jdk17
COPY boot_jdk_musl_amd64.tar.gz /jdk20/
RUN cd /jdk20 && tar --strip-components=1 -xzf boot_jdk_musl_amd64.tar.gz && rm /jdk20/boot_jdk_musl_amd64.tar.gz
ENV BOOT_JDK=/jdk20
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -25,7 +25,8 @@ RUN yum -y install centos-release-scl; \
wayland-devel-1.15.0-1.el7 \
wget-1.14-18.el7_6.1 \
which-2.20-7.el7 \
zip-3.0-11.el7
zip-3.0-11.el7 \
python3-3.6.8-17.el7
RUN mkdir .git && \
git config user.email "teamcity@jetbrains.com" && \
@@ -33,4 +34,40 @@ RUN mkdir .git && \
ENV LD_LIBRARY_PATH="/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib:/opt/rh/devtoolset-10/root/usr/lib64/dyninst:/opt/rh/devtoolset-10/root/usr/lib/dyninst:/opt/rh/devtoolset-10/root/usr/lib64:/opt/rh/devtoolset-10/root/usr/lib"
ENV PATH="/opt/rh/devtoolset-10/root/usr/bin::${PATH}"
ENV PKG_CONFIG_PATH="/opt/rh/devtoolset-10/root/usr/lib64/pkgconfig"
ENV PKG_CONFIG_PATH="/opt/rh/devtoolset-10/root/usr/lib64/pkgconfig"
# Build GLSLC
RUN curl -OL https://github.com/Kitware/CMake/releases/download/v3.27.5/cmake-3.27.5-linux-x86_64.tar.gz \
&& echo 138c68addae825b16ed78d792dafef5e0960194833f48bd77e7e0429c6bc081c *cmake-3.27.5-linux-x86_64.tar.gz | sha256sum -c - \
&& tar -xzf cmake-3.27.5-linux-x86_64.tar.gz \
&& rm cmake-3.27.5-linux-x86_64.tar.gz \
&& git clone https://github.com/google/shaderc --branch v2023.6 \
&& cd shaderc \
&& ./utils/git-sync-deps \
&& mkdir build \
&& cd build \
&& /cmake-3.27.5-linux-x86_64/bin/cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DSHADERC_SKIP_TESTS=ON \
-DSHADERC_SKIP_EXAMPLES=ON \
-DSHADERC_SKIP_COPYRIGHT_CHECK=ON \
.. \
&& make install
ENV PATH="/cmake-3.27.5-linux-x86_64/bin::${PATH}"
# Checkout Vulkan headers
RUN mkdir /vulkan \
&& cd /vulkan \
&& git init \
&& git remote add -f origin https://github.com/KhronosGroup/Vulkan-Headers.git \
&& git fetch origin \
&& git checkout v1.3.265 -- include \
&& rm -r .git \
&& mkdir /vulkan_hpp \
&& cd /vulkan_hpp \
&& git init \
&& git remote add -f origin https://github.com/KhronosGroup/Vulkan-Hpp.git \
&& git fetch origin \
&& git checkout v1.3.265 -- vulkan \
&& rm -r .git

View File

@@ -4,10 +4,10 @@ set -euo pipefail
set -x
# This script creates a Docker image suitable for building musl AArch64 variant
# of the JetBrains Runtime version 17.
# of the JetBrains Runtime version 21.
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=6b920559abafbe9bdef386a20ecf3a2f318bc1f0d8359eb1f95aee26606bbc70
BOOT_JDK_REMOTE_FILE=zulu20.32.11-ca-jdk20.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=eec57cf744c2438f695221f041d4804de3033ad33b6dba769d3359813ba3f90d
BOOT_JDK_LOCAL_FILE=boot_jdk_musl_aarch64.tar.gz
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
@@ -22,7 +22,7 @@ sha256sum -c - <<EOF
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
EOF
docker build -t jbr17buildenv -f Dockerfile.musl_aarch64 .
docker build -t jetbrains/runtime:jbr21env_musl_aarch64 -f Dockerfile.musl_aarch64 .
# NB: the resulting container can (and should) be used without the network
# connection (--network none) during build in order to reduce the chance

View File

@@ -4,10 +4,10 @@ set -euo pipefail
set -x
# This script creates a Docker image suitable for building musl-x64 variant
# of the JetBrains Runtime version 17.
# of the JetBrains Runtime version 21.
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=bcc5342011bd9f3643372aadbdfa68d47463ff0d8621668a0bdf2910614d95c6
BOOT_JDK_REMOTE_FILE=zulu20.32.11-ca-jdk20.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=fca5081dd6da847fcd06f5b755e58edae22d6784f21b81bf73da2b538f842c07
BOOT_JDK_LOCAL_FILE=boot_jdk_musl_amd64.tar.gz
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
@@ -22,7 +22,7 @@ sha256sum -c - <<EOF
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
EOF
docker build -t jbr17buildenv -f Dockerfile.musl_x64 .
docker build -t jetbrains/runtime:jbr21env_musl_x64 -f Dockerfile.musl_x64 .
# NB: the resulting container can (and should) be used without the network
# connection (--network none) during build in order to reduce the chance

View File

@@ -5,7 +5,7 @@ set -x
function check_bundle_type_maketest() {
# check whether last char is 't', if so remove it
if [ "${bundle_type: -1}" == "t" ]; then
if [ "${bundle_type: -1}" == "t" ] && [ "${bundle_type: -2}" == "ft" ]; then
bundle_type="${bundle_type%?}"
do_maketest=1
else
@@ -94,6 +94,12 @@ esac
WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS="--with-native-debug-symbols=zipped"
if [ "$bundle_type" == "nomodft" ]; then
WITH_BUNDLED_FREETYPE="--with-freetype=bundled"
else
WITH_BUNDLED_FREETYPE=""
fi
REPRODUCIBLE_BUILD_OPTS="--with-source-date=$SOURCE_DATE_EPOCH
--with-hotspot-build-time=$BUILD_TIME
--with-copyright-year=$COPYRIGHT_YEAR

View File

@@ -38,6 +38,7 @@ function do_configure {
$STATIC_CONF_ARGS \
$REPRODUCIBLE_BUILD_OPTS \
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
$WITH_BUNDLED_FREETYPE \
|| do_exit $?
}
@@ -100,6 +101,8 @@ function create_image_bundle {
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-aarch64-server-release
jbr_name_postfix=""
case "$bundle_type" in
"jcef")
do_reset_changes=1

View File

@@ -38,6 +38,7 @@ function do_configure {
$STATIC_CONF_ARGS \
$REPRODUCIBLE_BUILD_OPTS \
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
$WITH_BUNDLED_FREETYPE \
|| do_exit $?
}
@@ -99,16 +100,24 @@ function create_image_bundle {
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-x86_64-server-release
jbr_name_postfix=""
case "$bundle_type" in
"jcef")
do_reset_changes=1
jbr_name_postfix="_${bundle_type}"
do_maketest=1
;;
"nomod" | "")
bundle_type=""
;;
"nomodft" | "")
bundle_type=""
jbr_name_postfix="_ft"
;;
"fd")
do_reset_changes=1
jbr_name_postfix="_${bundle_type}"
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=linux-x86_64-server-fastdebug
;;
@@ -132,11 +141,7 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
jbr_name_postfix="_${bundle_type}"
cat $JCEF_PATH/jcef.version >> $JSDK/release
else
jbr_name_postfix=""
fi
# create runtime image bundle

View File

@@ -34,6 +34,9 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
(expecting the headers under PATH/include)])])
AC_ARG_WITH(wayland-include, [AS_HELP_STRING([--with-wayland-include],
[specify directory for the wayland include files])])
AC_ARG_WITH(wayland-lib, [AS_HELP_STRING([--with-wayland-lib],
[specify directory for the wayland library files])])
if test "x$NEEDS_LIB_WAYLAND" = xfalse; then
if (test "x${with_wayland}" != x && test "x${with_wayland}" != xno) || \
@@ -73,6 +76,10 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
AC_MSG_ERROR([Can't find 'wayland-client.h' and 'wayland-cursor.h' under ${with_wayland_include} given with the --with-wayland-include option.])
fi
fi
if test "x${with_wayland_lib}" != x; then
WAYLAND_LIBS="-L${with_wayland_lib} -lwayland-client -lwayland-cursor"
fi
if test "x$WAYLAND_FOUND" = xno; then
# Are the wayland headers installed in the default /usr/include location?
AC_CHECK_HEADERS([wayland-client.h wayland-cursor.h],
@@ -97,7 +104,13 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
[specify whether we use vulkan])])
AC_ARG_WITH(vulkan-include, [AS_HELP_STRING([--with-vulkan-include],
[specify directory for the vulkan include files])])
[specify directory for the vulkan include files ({with-vulkan-include}/vulkan/vulkan.h)])])
AC_ARG_WITH(vulkan-hpp, [AS_HELP_STRING([--with-vulkan-hpp],
[specify directory for the vulkan-hpp include files ({with-vulkan-hpp}/vulkan/vulkan_raii.hpp)])])
AC_ARG_WITH(vulkan-shader-compiler, [AS_HELP_STRING([--with-vulkan-shader-compiler],
[specify which shader compiler to use: glslc/glslangValidator])])
if test "x$SUPPORTS_LIB_VULKAN" = xfalse; then
@@ -117,21 +130,38 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
VULKAN_FOUND=no
if test "x${with_vulkan_include}" != x; then
AC_CHECK_HEADERS([${with_vulkan_include}/include/vulkan/vulkan.h],
[ VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -I${with_vulkan_include}/include -DVULKAN_ENABLED"
VULKAN_ENABLED=true
],
[ AC_MSG_ERROR([Can't find 'vulkan/vulkan.h' under '${with_vulkan_include}']) ]
)
AC_MSG_CHECKING([for vulkan.h])
if test -s "${with_vulkan_include}/vulkan/vulkan.h"; then
VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -I${with_vulkan_include} -DVULKAN_ENABLED"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([Can't find 'vulkan/vulkan.h' under '${with_vulkan_include}'])
fi
AC_MSG_CHECKING([for vulkan_raii.hpp])
if test "x${with_vulkan_hpp}" != x; then
VULKAN_FLAGS="-I${with_vulkan_hpp} ${VULKAN_FLAGS}"
VULKAN_HPP_DIR=${with_vulkan_hpp}
else
VULKAN_HPP_DIR=${with_vulkan_include}
fi
if test -s "$VULKAN_HPP_DIR/vulkan/vulkan_raii.hpp"; then
VULKAN_FOUND=yes
AC_MSG_RESULT([yes])
else
VULKAN_FOUND=no
AC_MSG_RESULT([no])
AC_MSG_ERROR([Can't find 'vulkan/vulkan_raii.hpp' under '$VULKAN_HPP_DIR'])
fi
fi
AC_LANG_PUSH([C++])
if test "x$VULKAN_FOUND" = xno; then
# Check vulkan sdk location
AC_CHECK_HEADERS([$VULKAN_SDK/include/vulkan/vulkan.h],
AC_CHECK_HEADERS([$VULKAN_SDK/include/vulkan/vulkan.h $VULKAN_SDK/include/vulkan/vulkan_raii.hpp],
[ VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -I${VULKAN_SDK}/include -DVULKAN_ENABLED"
VULKAN_ENABLED=true
],
[ VULKAN_FOUND=no; break ]
)
@@ -139,23 +169,44 @@ AC_DEFUN_ONCE([LIB_SETUP_WAYLAND],
if test "x$VULKAN_FOUND" = xno; then
# Check default /usr/include location
AC_CHECK_HEADERS([vulkan/vulkan.h],
AC_CHECK_HEADERS([vulkan/vulkan.h vulkan/vulkan_raii.hpp],
[ VULKAN_FOUND=yes
VULKAN_FLAGS="-DVK_USE_PLATFORM_WAYLAND_KHR -DVULKAN_ENABLED"
VULKAN_ENABLED=true
],
[ VULKAN_FOUND=no; break ]
)
fi
AC_LANG_POP([C++])
if test "x$VULKAN_FOUND" = xno; then
HELP_MSG_MISSING_DEPENDENCY([vulkan])
AC_MSG_ERROR([Could not find vulkan! $HELP_MSG ])
else
# Find shader compiler - glslc or glslangValidator
if (test "x${with_vulkan_shader_compiler}" = x || test "x${with_vulkan_shader_compiler}" = xglslc); then
UTIL_LOOKUP_PROGS(GLSLC, glslc)
SHADER_COMPILER="$GLSLC"
VULKAN_SHADER_COMPILER="glslc --target-env=vulkan1.2 -mfmt=num -o"
fi
if (test "x${with_vulkan_shader_compiler}" = x || test "x${with_vulkan_shader_compiler}" = xglslangValidator) && \
test "x$SHADER_COMPILER" = x; then
UTIL_LOOKUP_PROGS(GLSLANG, glslangValidator)
SHADER_COMPILER="$GLSLANG"
VULKAN_SHADER_COMPILER="glslangValidator --target-env vulkan1.2 -x -o"
fi
if test "x$SHADER_COMPILER" != x; then
VULKAN_ENABLED=true
else
AC_MSG_ERROR([Can't find shader compiler])
fi
fi
fi
fi
fi
AC_SUBST(VULKAN_FLAGS)
AC_SUBST(VULKAN_SHADER_COMPILER)
AC_SUBST(VULKAN_ENABLED)
AC_SUBST(WAYLAND_CFLAGS)
AC_SUBST(WAYLAND_LIBS)

View File

@@ -482,6 +482,7 @@ A11Y_JAWS_ANNOUNCING_ENABLED:=@A11Y_JAWS_ANNOUNCING_ENABLED@
WAYLAND_CFLAGS:=@WAYLAND_CFLAGS@
WAYLAND_LIBS:=@WAYLAND_LIBS@
VULKAN_FLAGS:=@VULKAN_FLAGS@
VULKAN_SHADER_COMPILER:=@VULKAN_SHADER_COMPILER@
VULKAN_ENABLED:=@VULKAN_ENABLED@
# The lowest required version of macosx

View File

@@ -219,6 +219,34 @@ ifeq ($(call isTargetOs, windows)+$(ENABLE_HEADLESS_ONLY)+$(A11Y_NVDA_ANNOUNCING
TARGETS += $(COPY_NVDA_DEPENDENCIES)
endif
# Compile Vulkan shaders
define compile-spirv
$(call MakeTargetDir)
$(VULKAN_SHADER_COMPILER) '$(call DecodeSpace, $@)' '$(call DecodeSpace, $<)'
endef
spirv-name = $(strip $1).h
ifeq ($(VULKAN_ENABLED), true)
$(eval $(call SetupCopyFiles, COMPILE_VULKAN_SHADERS, \
SRC := $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan, \
FILES := $(call FindFiles, $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan), \
DEST := $(SUPPORT_OUTPUTDIR)/headers/java.desktop/vulkan/spirv, \
MACRO := compile-spirv, \
NAME_MACRO := spirv-name, \
))
VULKAN_SHADER_LIST = $(SUPPORT_OUTPUTDIR)/headers/java.desktop/vulkan/shader_list.h
$(VULKAN_SHADER_LIST): $(COMPILE_VULKAN_SHADERS)
> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(foreach f, $(patsubst $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan/%,%,$(call FindFiles, $(TOPDIR)/src/$(MODULE)/share/glsl/vulkan)), \
$(ECHO) SHADER_ENTRY\($(subst .,$(COMMA),$(subst /,_,$f))\) >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) '#ifdef INCLUDE_BYTECODE' >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) '#include "spirv/$f.h"' >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) BYTECODE_END >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
$(ECHO) '#endif' >> $(VULKAN_SHADER_LIST) $(NEWLINE) \
)
$(BUILD_LIBAWT): $(VULKAN_SHADER_LIST)
endif
TARGETS += $(BUILD_LIBAWT)
################################################################################
@@ -354,6 +382,7 @@ ifeq ($(call isTargetOs, windows macosx), false)
common/font \
common/java2d/wl \
common/java2d/vulkan \
libvmahpp \
#
# Enable 'wakefield' extension for java.awt.Robot support
@@ -401,6 +430,8 @@ ifeq ($(call isTargetOs, windows macosx), false)
DISABLED_WARNINGS_CXX_gcc := undef, \
DISABLED_WARNINGS_clang := parentheses format undef \
logical-op-parentheses format-nonliteral int-conversion, \
DISABLED_WARNINGS_gcc_VKMemory.cpp := missing-field-initializers implicit-fallthrough parentheses, \
DISABLED_WARNINGS_clang_VKMemory.cpp := missing-field-initializers implicit-fallthrough parentheses, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN) \
-L$(INSTALL_LIBRARIES_HERE), \

View File

@@ -25,9 +25,13 @@
package com.jetbrains.internal;
import sun.security.action.GetBooleanAction;
import java.io.Serial;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -97,7 +101,8 @@ import static java.lang.invoke.MethodHandles.Lookup;
* user to directly create proxy object.
*/
public class JBRApi {
static final boolean VERBOSE = Boolean.getBoolean("jetbrains.api.verbose");
@SuppressWarnings("removal")
static final boolean VERBOSE = AccessController.doPrivileged(new GetBooleanAction("jetbrains.api.verbose"));
private static final Map<String, RegisteredProxyInfo> registeredProxyInfoByInterfaceName = new HashMap<>();
private static final Map<String, RegisteredProxyInfo> registeredProxyInfoByTargetName = new HashMap<>();
@@ -205,19 +210,22 @@ public class JBRApi {
return this;
}
@SuppressWarnings("removal")
public Object build() {
ProxyInfo info = ProxyInfo.resolve(this.info);
if (info == null) return null;
ProxyGenerator generator = new ProxyGenerator(info);
if (!generator.areAllMethodsImplemented()) return null;
generator.defineClasses();
MethodHandle constructor = generator.findConstructor();
generator.init();
try {
return constructor.invoke();
} catch (Throwable e) {
throw new RuntimeException(e);
}
return AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ProxyInfo info = ProxyInfo.resolve(this.info);
if (info == null) return null;
ProxyGenerator generator = new ProxyGenerator(info);
if (!generator.areAllMethodsImplemented()) return null;
generator.defineClasses();
MethodHandle constructor = generator.findConstructor();
generator.init();
try {
return constructor.invoke();
} catch (Throwable e) {
throw new RuntimeException(e);
}
});
}
}

View File

@@ -190,6 +190,10 @@ public final class LWCToolkit extends LWToolkit {
return getKeyboardLayoutList(false).contains(layoutName);
}
public static boolean isKeyboardLayoutInstalled(String layoutName) {
return getKeyboardLayoutList(true).contains(layoutName);
}
// Listens to EDT state in invokeAndWait() and disposes the invocation event
// when EDT becomes free but the invocation event is not yet dispatched (considered lost).
// This prevents a deadlock and makes the invocation return some default result.

View File

@@ -35,6 +35,7 @@
#import "JNIUtilities.h"
#import "jni_util.h"
#import "PropertiesUtilities.h"
#import "sun_lwawt_macosx_CPlatformWindow.h"
#import <Carbon/Carbon.h>
@@ -850,7 +851,7 @@ static void debugPrintNSEvent(NSEvent* event, const char* comment) {
- (BOOL)replaceAccessibleTextSelection:(NSString *)text
{
id focused = [self accessibilityFocusedUIElement];
if (![focused respondsToSelector:@selector(setAccessibilitySelectedText)]) return NO;
if (![focused respondsToSelector:@selector(setAccessibilitySelectedText:)]) return NO;
[focused setAccessibilitySelectedText:text];
return YES;
}
@@ -1096,6 +1097,43 @@ static jclass jc_CInputMethod = NULL;
#define GET_CIM_CLASS_RETURN(ret) \
GET_CLASS_RETURN(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod", ret);
- (NSInteger) windowLevel
{
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [windowLevel]\n");
#endif // IM_DEBUG
NSWindow* const ownerWindow = [self window];
if (ownerWindow == nil) {
return NSNormalWindowLevel;
}
const NSWindowLevel ownerWindowLevel = [ownerWindow level];
if ( (ownerWindowLevel != NSNormalWindowLevel) && (ownerWindowLevel != NSFloatingWindowLevel) ) {
// the window level has been overridden, let's believe it
return ownerWindowLevel;
}
AWTWindow* const delegate = (AWTWindow*)[ownerWindow delegate];
if (delegate == nil) {
return ownerWindowLevel;
}
const jint styleBits = [delegate styleBits];
const BOOL isPopup = ( (styleBits & sun_lwawt_macosx_CPlatformWindow_IS_POPUP) != 0 );
if (isPopup) {
return NSPopUpMenuWindowLevel;
}
const BOOL isModal = ( (styleBits & sun_lwawt_macosx_CPlatformWindow_IS_MODAL) != 0 );
if (isModal) {
return NSFloatingWindowLevel;
}
return ownerWindowLevel;
}
- (void) insertText:(id)aString replacementRange:(NSRange)replacementRange
{
#ifdef IM_DEBUG

View File

@@ -46,7 +46,8 @@
extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo);
extern BOOL isDisplaySyncEnabled();
extern BOOL MTLLayer_isExtraRedrawEnabled();
static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = {
{{-1.0, 1.0}, {0.0, 0.0}},
{{1.0, 1.0}, {1.0, 0.0}},
@@ -599,6 +600,10 @@ CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp*
J2dTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_startRedraw: ctx=%p layer=%p", self, layer);
_displayLinkCount = KEEP_ALIVE_COUNT;
[_layers addObject:layer];
if (MTLLayer_isExtraRedrawEnabled()) {
// Request for redraw before starting display link to avoid rendering problem on M2 processor
[layer setNeedsDisplay];
}
if (_displayLink != NULL && !CVDisplayLinkIsRunning(_displayLink)) {
CVDisplayLinkStart(_displayLink);
J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_CVDisplayLinkStart: ctx=%p", self);

View File

@@ -23,6 +23,7 @@
* questions.
*/
#import <sys/sysctl.h>
#import "PropertiesUtilities.h"
#import "MTLGraphicsConfig.h"
#import "MTLLayer.h"
@@ -59,6 +60,56 @@ BOOL isColorMatchingEnabled() {
return (BOOL)colorMatchingEnabled;
}
BOOL MTLLayer_isM2CPU() {
static int m2CPU = -1;
if (m2CPU == -1) {
char cpuBrandDefaultStr[16];
char *cpuBrand = cpuBrandDefaultStr;
size_t len;
sysctlbyname("machdep.cpu.brand_string", NULL, &len, NULL, 0);
if (len >= sizeof(cpuBrandDefaultStr)) {
cpuBrand = malloc(len);
}
sysctlbyname("machdep.cpu.brand_string", cpuBrand, &len, NULL, 0);
m2CPU = strstr(cpuBrand, "M2") != NULL;
J2dRlsTraceLn2(J2D_TRACE_INFO, "MTLLayer_isM2CPU: %d (%s)", m2CPU, cpuBrand);
if (cpuBrand != cpuBrandDefaultStr) {
free(cpuBrand);
}
}
return m2CPU;
}
BOOL MTLLayer_isSpansDisplays() {
static int spansDisplays = -1;
if (spansDisplays == -1) {
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSDictionary<NSString*,id> *spaces = [defaults persistentDomainForName:@"com.apple.spaces"];
spansDisplays = [(NSNumber*)[spaces valueForKey:@"spans-displays"] intValue];
J2dRlsTraceLn1(J2D_TRACE_INFO, "MTLLayer_isSpansDisplays: %d", spansDisplays);
}
return spansDisplays;
}
BOOL MTLLayer_isExtraRedrawEnabled() {
static int redrawEnabled = -1;
if (redrawEnabled == -1) {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
if (env == NULL) return NO;
NSString *syncEnabledProp = [PropertiesUtilities javaSystemPropertyForKey:@"sun.java2d.metal.extraRedraw"
withEnv:env];
redrawEnabled = [@"false" isCaseInsensitiveLike:syncEnabledProp] ? NO : -1;
if (redrawEnabled == -1) {
redrawEnabled = [@"true" isCaseInsensitiveLike:syncEnabledProp] ?
YES : MTLLayer_isSpansDisplays() && MTLLayer_isM2CPU();
}
J2dRlsTraceLn1(J2D_TRACE_INFO, "MTLLayer_isExtraRedrawEnabled: %d", redrawEnabled);
}
return (BOOL)redrawEnabled;
}
@implementation MTLLayer
- (id) initWithJavaLayer:(jobject)layer
@@ -87,7 +138,11 @@ BOOL isColorMatchingEnabled() {
[actions release];
self.topInset = 0;
self.leftInset = 0;
self.framebufferOnly = YES;
// Validation with MTL_DEBUG_LAYER=1 environment variable
// prohibits blit operations on to the drawable texture
// obtained from a MTLLayer with framebufferOnly=YES
self.framebufferOnly = NO;
self.nextDrawableCount = 0;
self.opaque = YES;
self.redrawCount = 0;

View File

@@ -36,9 +36,14 @@ import java.util.stream.Collectors;
public class FontExtensions {
private interface FontExtension {
FontExtension INSTANCE = (FontExtension) JBRApi.internalServiceBuilder(MethodHandles.lookup())
.withStatic("getFeatures", "getFeatures", "java.awt.Font").build();
.withStatic("getFeatures", "getFeatures", "java.awt.Font")
.withStatic("isComplexRendering", "isComplexRendering", "java.awt.Font")
.withStatic("isKerning", "isKerning", "java.awt.Font")
.build();
TreeMap<String, Integer> getFeatures(Font font);
boolean isComplexRendering(Font font);
boolean isKerning(Font font);
}
public static String[] featuresToStringArray(Map<String, Integer> features) {
@@ -49,4 +54,12 @@ public class FontExtensions {
public static TreeMap<String, Integer> getFeatures(Font font) {
return FontExtension.INSTANCE.getFeatures(font);
}
public static boolean isComplexRendering(Font font) {
return FontExtension.INSTANCE.isComplexRendering(font);
}
public static boolean isKerning(Font font) {
return FontExtension.INSTANCE.isKerning(font);
}
}

View File

@@ -2719,29 +2719,17 @@ public class Font implements java.io.Serializable
(limit - beginIndex));
}
// this code should be in textlayout
// quick check for simple text, assume GV ok to use if simple
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc);
return metrics.charsBounds(chars, beginIndex, limit - beginIndex);
}
boolean simple = (values == null ||
(values.getKerning() == 0
&& values.getLigatures() == 0
&& values.getTracking() == 0
&& values.getBaselineTransform() == null)) && !anyEnabledFeatures();
if (simple) {
simple = ! FontUtilities.isComplexText(chars, beginIndex, limit);
}
private static boolean isComplexRendering(Font font) {
return (font.values != null && (font.values.getLigatures() != 0 || font.values.getTracking() != 0 ||
font.values.getBaselineTransform() != null)) || font.anyEnabledFeatures();
}
if (simple || ((limit - beginIndex) == 0)) {
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc);
return metrics.getSimpleBounds(chars, beginIndex, limit-beginIndex);
} else {
// need char array constructor on textlayout
String str = new String(chars, beginIndex, limit - beginIndex);
TextLayout tl = new TextLayout(str, this, frc);
return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(),
tl.getAscent() + tl.getDescent() +
tl.getLeading());
}
private static boolean isKerning(Font font) {
return font.values != null && (font.values.getKerning() != 0);
}
/**

View File

@@ -38,8 +38,11 @@ import java.io.ObjectOutputStream;
import java.io.Serial;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.jetbrains.desktop.FontExtensions;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
@@ -432,16 +435,13 @@ public final class FontDesignMetrics extends FontMetrics {
return frc;
}
public int charWidth(char ch) {
private float preciseCharWidth(char ch) {
// default metrics for compatibility with legacy code
float w;
if (ch < 0x100) {
w = getLatinCharWidth(ch);
}
else {
w = handleCharWidth(ch);
}
return (int)(0.5 + w);
return (ch < 0x100) ? getLatinCharWidth(ch) : handleCharWidth(ch);
}
public int charWidth(char ch) {
return Math.round(preciseCharWidth(ch));
}
public int charWidth(int ch) {
@@ -451,93 +451,111 @@ public final class FontDesignMetrics extends FontMetrics {
float w = handleCharWidth(ch);
return (int)(0.5 + w);
return Math.round(w);
}
private Rectangle2D.Float textLayoutBounds(Object data, int off, int len) {
String str = data instanceof String ? ((String) data).substring(off, off + len) :
new String((char[]) data, off, len);
TextLayout tl = new TextLayout(str, font, frc);
return new Rectangle2D.Float(0, -tl.getAscent(),
tl.getAdvance(), tl.getAscent() + tl.getDescent() + tl.getLeading());
}
private char getChar(Object data, int i) {
return data instanceof String ? ((String) data).charAt(i) : ((char[]) data)[i];
}
final int ADVANCES_FAST_KEY_LIMIT = 0x100;
private HashMap<Integer, Float> advances = new HashMap<>();
private float[] advancesFast = new float[ADVANCES_FAST_KEY_LIMIT * ADVANCES_FAST_KEY_LIMIT];
private Rectangle2D.Float dataBounds(Object data, int off, int len) {
assert (data instanceof String || data instanceof char[]);
float width = 0;
if (FontExtensions.isComplexRendering(font) && len > 0) {
return textLayoutBounds(data, off, len);
}
float height = ascent + descent + leading;
if (len == 0 || len == 1 && !FontUtilities.isNonSimpleChar(getChar(data, off))) {
width = len > 0 ? preciseCharWidth(getChar(data, off)) : 0f;
return new Rectangle2D.Float(0f, -ascent, width, height);
}
boolean isKerning = FontExtensions.isKerning(font);
float consecutiveDoubleCharacterWidth = 0f;
char prev = 0;
for (int i = off; i < off + len; i++) {
char cur = getChar(data, i);
if (FontUtilities.isNonSimpleChar(cur)) {
return textLayoutBounds(data, off, len);
} else {
// Correct width of string with kerning calculates by text LayoutBounds but it could be slow.
// Below is description of optimized algorithm for correct calculating width of text with kerning:
// proof:
// base: kerningWidth('c1') = plainWidth('c1')
// induction: kerningWidth('c1..cN-1cN') =
// kerningWidth('c1..cN-1') + kerningWidth('cN-1cN') - plainWidth('cN-1')
// final: kerningWidth('c1..cN') = kerningWidth('c1c2') + ... + kerningWidth('cN-1cN')
// - (plainWidth('c2') + ... + plainWidth('cN-1'))
// remark: for reducing calculation of kerningWidth('c1c2') using caching
if (isKerning && i > off) {
// fast path
if (prev < ADVANCES_FAST_KEY_LIMIT && cur < ADVANCES_FAST_KEY_LIMIT) {
int key = (prev << 8) | cur;
if (advancesFast[key] == 0.0f) {
advancesFast[key] = textLayoutBounds(data, i - 1, 2).width;
}
consecutiveDoubleCharacterWidth += advancesFast[key];
// common solution
} else {
int key = (prev << 16) | (0xffff & cur);
advances.putIfAbsent(key, textLayoutBounds(data, i - 1, 2).width);
consecutiveDoubleCharacterWidth += advances.get(key);
}
}
width += preciseCharWidth(cur);
}
prev = cur;
}
if (isKerning) {
width = consecutiveDoubleCharacterWidth -
(width - preciseCharWidth(getChar(data, off)) - preciseCharWidth(getChar(data, off + len - 1)));
}
return new Rectangle2D.Float(0f, -ascent, width, height);
}
public Rectangle2D.Float charsBounds(char[] data, int off, int len) {
return dataBounds(data, off, len);
}
private int dataWidth(Object data, int off, int len) {
return Math.round((float) dataBounds(data, off, len).getWidth());
}
public int stringWidth(String str) {
float width = 0;
if (font.hasLayoutAttributes()) {
/* TextLayout throws IAE for null, so throw NPE explicitly */
if (str == null) {
throw new NullPointerException("str is null");
}
if (str.length() == 0) {
return 0;
}
width = new TextLayout(str, font, frc).getAdvance();
} else {
int length = str.length();
for (int i=0; i < length; i++) {
char ch = str.charAt(i);
if (ch < 0x100) {
width += getLatinCharWidth(ch);
} else if (FontUtilities.isNonSimpleChar(ch)) {
width = new TextLayout(str, font, frc).getAdvance();
break;
} else {
width += handleCharWidth(ch);
}
}
if (str == null) {
throw new NullPointerException("str is null");
}
return (int) (0.5 + width);
return dataWidth(str, 0, str.length());
}
public int charsWidth(char[] data, int off, int len) {
float width = 0;
if (font.hasLayoutAttributes()) {
if (len == 0) {
return 0;
}
String str = new String(data, off, len);
width = new TextLayout(str, font, frc).getAdvance();
} else {
/* Explicit test needed to satisfy superclass spec */
if (len < 0) {
throw new IndexOutOfBoundsException("len="+len);
}
int limit = off + len;
for (int i=off; i < limit; i++) {
char ch = data[i];
if (ch < 0x100) {
width += getLatinCharWidth(ch);
} else if (FontUtilities.isNonSimpleChar(ch)) {
String str = new String(data, off, len);
width = new TextLayout(str, font, frc).getAdvance();
break;
} else {
width += handleCharWidth(ch);
}
}
/* Explicit test needed to satisfy superclass spec */
if (len < 0) {
throw new IndexOutOfBoundsException("len="+len);
}
return (int) (0.5 + width);
return dataWidth(data, off, len);
}
/**
* This method is called from java.awt.Font only after verifying
* the arguments and that the text is simple and there are no
* layout attributes, font transform etc.
*/
public Rectangle2D getSimpleBounds(char[] data, int off, int len) {
float width = 0;
int limit = off + len;
for (int i=off; i < limit; i++) {
char ch = data[i];
if (ch < 0x100) {
width += getLatinCharWidth(ch);
} else {
width += handleCharWidth(ch);
}
}
float height = ascent + descent + leading;
return new Rectangle2D.Float(0f, -ascent, width, height);
}
/**
* Gets the advance widths of the first 256 characters in the
* {@code Font}. The advance is the
@@ -557,7 +575,7 @@ public final class FontDesignMetrics extends FontMetrics {
if (w == UNKNOWN_WIDTH) {
w = advCache[ch] = handleCharWidth(ch);
}
widths[ch] = (int) (0.5 + w);
widths[ch] = Math.round(w);
}
return widths;
}

View File

@@ -1068,9 +1068,13 @@ public class TrueTypeFont extends FileFont {
metrics[offset+3] = ulSize * pointSize;
}
private String makeString(byte[] bytes, int len,
private String makeString(ByteBuffer buffer, int bufferPtr, int len,
short platformID, short encoding) {
buffer.position(bufferPtr);
byte[] bytes = new byte[len];
buffer.get(bytes, 0, len);
if (platformID == MAC_PLATFORM_ID) {
encoding = -1; // hack so we can re-use the code below.
}
@@ -1136,7 +1140,6 @@ public class TrueTypeFont extends FileFont {
protected void initNames() {
byte[] name = new byte[256];
ByteBuffer buffer = getTableBuffer(nameTag);
if (buffer != null) {
@@ -1187,9 +1190,7 @@ public class TrueTypeFont extends FileFont {
(localeFamilyName == null &&
(compatible = isLanguageCompatible(langID))))
{
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
tmpName = makeString(name, nameLen, platformID, encodingID);
tmpName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
if (familyName == null || langID == ENGLISH_LOCALE_ID){
familyName = tmpName;
}
@@ -1220,9 +1221,7 @@ public class TrueTypeFont extends FileFont {
(localeFullName == null &&
(compatible = isLanguageCompatible(langID))))
{
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
tmpName = makeString(name, nameLen, platformID, encodingID);
tmpName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
if (fullName == null || langID == ENGLISH_LOCALE_ID) {
fullName = tmpName;
@@ -1237,41 +1236,31 @@ public class TrueTypeFont extends FileFont {
case SUBFAMILY_NAME_ID:
if (subfamilyName == null || langID == ENGLISH_LOCALE_ID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
subfamilyName = makeString(name, nameLen, platformID, encodingID);
subfamilyName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
}
break;
case VERSION_NAME_ID:
if (version == null || langID == ENGLISH_LOCALE_ID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
version = parseVersion(makeString(name, nameLen, platformID, encodingID));
version = parseVersion(makeString(buffer, namePtr, nameLen, platformID, encodingID));
}
break;
case POSTSCRIPT_NAME_ID:
if (postScriptName == null || langID == ENGLISH_LOCALE_ID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
postScriptName = makeString(name, nameLen, platformID, encodingID);
postScriptName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
}
break;
case TYPOGRAPHIC_FAMILY_NAME_ID:
if (typographicFamilyName == null || langID == ENGLISH_LOCALE_ID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
typographicFamilyName = makeString(name, nameLen, platformID, encodingID);
typographicFamilyName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
}
break;
case TYPOGRAPHIC_SUBFAMILY_NAME_ID:
if (typographicSubfamilyName == null || langID == ENGLISH_LOCALE_ID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
typographicSubfamilyName = makeString(name, nameLen, platformID, encodingID);
typographicSubfamilyName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
}
break;
}
@@ -1330,9 +1319,7 @@ public class TrueTypeFont extends FileFont {
if (nameID == findNameID &&
((foundName == null && langID == ENGLISH_LOCALE_ID)
|| langID == findLocaleID)) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
foundName = makeString(name, nameLen, platformID, encodingID);
foundName = makeString(buffer, namePtr, nameLen, platformID, encodingID);
if (langID == findLocaleID) {
return foundName;
}
@@ -1671,9 +1658,7 @@ public class TrueTypeFont extends FileFont {
int namePtr = (((int) sbuffer.get()) & 0xffff) + stringPtr;
if (nameID == requestedID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
names.add(makeString(name, nameLen, platformID, encodingID));
names.add(makeString(buffer, namePtr, nameLen, platformID, encodingID));
}
}
}

View File

@@ -0,0 +1,8 @@
#version 450
layout(location = 0) in vec4 inColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = inColor;
}

View File

@@ -0,0 +1,21 @@
#version 450
layout(push_constant) uniform Push {
vec2 invViewport2; // 2.0/viewport
} push;
vec4 colors[3] = vec4[](
vec4(1,0,0,1),
vec4(0,1,0,1),
vec4(0,0,1,1)
);
layout(location = 0) in vec2 inPosition;
layout(location = 0) out vec4 outColor;
void main() {
outColor = colors[gl_VertexIndex % 3];
gl_Position = vec4(inPosition * push.invViewport2 - 1.0, 0.0, 1.0);
gl_PointSize = 1.0f;
}

View File

@@ -27,16 +27,20 @@
#include "VKBase.h"
#include <Trace.h>
#include <set>
#if defined(DEBUG)
#include <csignal>
#endif
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 0, 0);
static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
bool VKGraphicsEnvironment::_verbose = false;
int VKGraphicsEnvironment::_requested_device_number = -1;
std::unique_ptr<VKGraphicsEnvironment> VKGraphicsEnvironment::_ge_instance = nullptr;
// ========== Vulkan instance ==========
// ========== Graphics environment ==========
#if defined(DEBUG)
static vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
static VkBool32 debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
@@ -57,127 +61,13 @@ static VkBool32 debugCallback(
J2dRlsTraceLn(level, data->pMessage);
// TODO if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) ABORT?
if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
raise(SIGABRT);
}
return 0;
}
#endif
// ========== Vulkan device ==========
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
#endif
class PhysicalDevice : vk::raii::PhysicalDevice {
friend class VKDevice;
bool _supported = false;
std::vector<const char*> _enabled_layers, _enabled_extensions;
int _queue_family = -1;
public:
int queue_family() const {
return _queue_family;
}
std::vector<const char *> & enabled_layers() {
return _enabled_layers;
}
std::vector<const char *> & enabled_extensions() {
return _enabled_extensions;
}
explicit PhysicalDevice(vk::raii::PhysicalDevice&& handle) : vk::raii::PhysicalDevice(std::move(handle)) {
const auto& properties = getProperties();
const auto& queueFamilies = getQueueFamilyProperties();
J2dRlsTrace5(J2D_TRACE_INFO, "Vulkan: Found device %s (%d.%d.%d, %s)\n",
(const char*) properties.deviceName,
VK_API_VERSION_MAJOR(properties.apiVersion),
VK_API_VERSION_MINOR(properties.apiVersion),
VK_API_VERSION_PATCH(properties.apiVersion),
vk::to_string(properties.deviceType).c_str());
if (properties.apiVersion < REQUIRED_VULKAN_VERSION) {
J2dRlsTrace(J2D_TRACE_INFO, " Unsupported Vulkan version\n");
return;
}
// Check supported queue families.
for (unsigned int i = 0; i < queueFamilies.size(); i++) {
const auto& family = queueFamilies[i];
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
bool presentationSupported = getWaylandPresentationSupportKHR(i, *wl_display);
#endif
char logFlags[5] {
family.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-',
family.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-',
family.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-',
family.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-',
presentationSupported ? 'P' : '-'
};
J2dRlsTrace3(J2D_TRACE_INFO, " %d queues in family (%.*s)\n", family.queueCount, 5, logFlags);
// TODO use compute workloads? Separate transfer-only DMA queue?
if (_queue_family == -1 && (family.queueFlags & vk::QueueFlagBits::eGraphics) && presentationSupported) {
_queue_family = i;
}
}
if (_queue_family == -1) {
J2dRlsTrace(J2D_TRACE_INFO, " No suitable queue\n");
return;
}
// Populate maps and log supported layers & extensions.
std::set<std::string> layers, extensions;
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device layers:\n");
for (auto& l : enumerateDeviceLayerProperties()) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) l.layerName);
layers.emplace((char*) l.layerName);
}
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device extensions:\n");
for (auto& e : enumerateDeviceExtensionProperties(nullptr)) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) e.extensionName);
extensions.emplace((char*) e.extensionName);
}
// Check required layers & extensions.
_enabled_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
bool requiredNotFound = false;
for (auto e : _enabled_extensions) {
if (extensions.find(e) == extensions.end()) {
J2dRlsTrace1(J2D_TRACE_INFO, " Required device extension not supported: %s\n", (char*) e);
requiredNotFound = true;
}
}
if (requiredNotFound) return;
// Validation layer
#ifdef DEBUG
if (layers.find(VALIDATION_LAYER_NAME) != layers.end()) {
_enabled_layers.push_back(VALIDATION_LAYER_NAME);
} else {
J2dRlsTrace1(J2D_TRACE_INFO, " %s device layer is not supported\n", VALIDATION_LAYER_NAME);
}
#endif
// This device is supported
_supported = true;
}
operator bool() const {
vk::PhysicalDevice handle = **this;
return handle && _supported;
}
uint32_t getMaxImageDimension2D() {
const auto& properties = getProperties();
return properties.limits.maxImageDimension2D;
}
};
VKGraphicsEnvironment *VKGraphicsEnvironment::graphics_environment() {
if (!_ge_instance) {
try {
@@ -192,7 +82,7 @@ VKGraphicsEnvironment *VKGraphicsEnvironment::graphics_environment() {
}
VKGraphicsEnvironment::VKGraphicsEnvironment() :
_vk_context(), _vk_instance(nullptr), _default_device(-1) {
_vk_context(), _vk_instance(nullptr), _default_device(nullptr) {
// Load library.
uint32_t version = _vk_context.enumerateInstanceVersion();
J2dRlsTrace3(J2D_TRACE_INFO, "Vulkan: Available (%d.%d.%d)\n",
@@ -231,9 +121,9 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
}
// Configure validation
#ifdef DEBUG
std::array<vk::ValidationFeatureEnableEXT, 4> enabledValidationFeatures = {
vk::ValidationFeatureEnableEXT::eGpuAssisted,
vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot,
std::array<vk::ValidationFeatureEnableEXT, 2> enabledValidationFeatures = {
// vk::ValidationFeatureEnableEXT::eGpuAssisted, // TODO GPU assisted validation is available only from Vulkan 1.1
// vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot,
vk::ValidationFeatureEnableEXT::eBestPractices,
vk::ValidationFeatureEnableEXT::eSynchronizationValidation
};
@@ -272,7 +162,7 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
// Create debug messenger
#if defined(DEBUG)
if (pNext) {
debugMessenger = vk::raii::DebugUtilsMessengerEXT(_vk_instance, vk::DebugUtilsMessengerCreateInfoEXT {
_debugMessenger = vk::raii::DebugUtilsMessengerEXT(_vk_instance, vk::DebugUtilsMessengerCreateInfoEXT {
/*flags*/ {},
/*messageSeverity*/ vk::DebugUtilsMessageSeverityFlagBitsEXT::eError |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
@@ -289,26 +179,43 @@ VKGraphicsEnvironment::VKGraphicsEnvironment() :
// Find suitable devices.
for (auto &handle: _vk_instance.enumeratePhysicalDevices()) {
PhysicalDevice physicalDevice{std::move(handle)};
if (physicalDevice) { // Supported.
_physical_devices.push_back(std::move(physicalDevice));
VKDevice device {*_vk_instance, std::move(handle)};
if (device.supported()) {
_devices.push_back(std::make_unique<VKDevice>(std::move(device)));
}
}
if (_physical_devices.empty()) {
if (_devices.empty()) {
throw std::runtime_error("Vulkan: No suitable device found");
}
// Create virtual device for a physical device.
// TODO system property for manual choice of GPU
// TODO integrated/discrete presets
// TODO performance/power saving mode switch on the fly?
_default_physical_device = 0; // TODO pick first just to check hat virtual device creation works
_devices.push_back(std::move(VKDevice{_physical_devices[_default_physical_device]}));
_default_device = 0;
}
int _default_device_number = 0; // TODO pick first just to check that virtual device creation works
if (_verbose) {
fprintf(stderr, "Vulkan graphics devices:\n");
}
_requested_device_number = (_requested_device_number == -1) ? 0 : _requested_device_number;
if (_requested_device_number < 0 || _requested_device_number >= static_cast<int>(_devices.size())) {
if (_verbose) {
fprintf(stderr, " Requested device number (%d) not found, fallback to 0\n", _requested_device_number);
}
_requested_device_number = 0;
}
_default_device_number = _requested_device_number;
if (_verbose) {
for (auto devIter = _devices.begin(); devIter != _devices.end(); devIter++) {
auto devNum = std::distance(begin(_devices), devIter);
fprintf(stderr, " %c%ld: %s\n", devNum == _default_device_number ? '*' : ' ',
devNum, (*devIter)->name().c_str());
}
fprintf(stderr, "\n");
}
_default_device = &*_devices[_default_device_number]; // TODO pick first just to check hat virtual device creation works
_default_device->init();
uint32_t VKGraphicsEnvironment::max_texture_size() {
return _physical_devices[_default_physical_device].getMaxImageDimension2D();
}
vk::raii::Instance& VKGraphicsEnvironment::vk_instance() {
@@ -320,41 +227,227 @@ void VKGraphicsEnvironment::dispose() {
}
VKDevice& VKGraphicsEnvironment::default_device() {
return _devices[_default_device];
return *_default_device;
}
// ========== Vulkan device ==========
VKDevice::VKDevice(PhysicalDevice& physicalDevice) : vk::raii::Device(nullptr), _command_pool(nullptr) {
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
#endif
VKDevice::VKDevice(vk::Instance instance, vk::raii::PhysicalDevice&& handle) :
vk::raii::Device(nullptr), vk::raii::PhysicalDevice(nullptr), _instance(instance) {
auto featuresChain = handle.getFeatures2<vk::PhysicalDeviceFeatures2,
vk::PhysicalDeviceVulkan11Features,
vk::PhysicalDeviceVulkan12Features>();
const auto& features10 = featuresChain.get<vk::PhysicalDeviceFeatures2>().features;
const auto& features11 = featuresChain.get<vk::PhysicalDeviceVulkan11Features>();
const auto& features12 = featuresChain.get<vk::PhysicalDeviceVulkan12Features>();
auto propertiesChain = handle.getProperties2<vk::PhysicalDeviceProperties2,
vk::PhysicalDeviceVulkan11Properties,
vk::PhysicalDeviceVulkan12Properties>();
const auto& properties10 = propertiesChain.get<vk::PhysicalDeviceProperties2>().properties;
const auto& properties11 = propertiesChain.get<vk::PhysicalDeviceVulkan11Properties>();
const auto& properties12 = propertiesChain.get<vk::PhysicalDeviceVulkan12Properties>();
const auto& queueFamilies = handle.getQueueFamilyProperties();
_name = (const char*) properties10.deviceName;
J2dRlsTrace5(J2D_TRACE_INFO, "Vulkan: Found device %s (%d.%d.%d, %s)\n",
(const char*) properties10.deviceName,
VK_API_VERSION_MAJOR(properties10.apiVersion),
VK_API_VERSION_MINOR(properties10.apiVersion),
VK_API_VERSION_PATCH(properties10.apiVersion),
vk::to_string(properties10.deviceType).c_str());
// Check API version.
if (properties10.apiVersion < REQUIRED_VULKAN_VERSION) {
J2dRlsTrace(J2D_TRACE_INFO, " Unsupported Vulkan version\n");
return;
}
// Check supported features.
if (!features10.logicOp) {
J2dRlsTrace(J2D_TRACE_INFO, " Logic op not supported\n");
return;
}
if (!features12.timelineSemaphore) {
J2dRlsTrace(J2D_TRACE_INFO, " Timeline semaphore not supported\n");
return;
}
// Check supported queue families.
for (unsigned int i = 0; i < queueFamilies.size(); i++) {
const auto& family = queueFamilies[i];
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
bool presentationSupported = handle.getWaylandPresentationSupportKHR(i, *wl_display);
#endif
char logFlags[5] {
family.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-',
family.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-',
family.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-',
family.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-',
presentationSupported ? 'P' : '-'
};
J2dRlsTrace3(J2D_TRACE_INFO, " %d queues in family (%.*s)\n", family.queueCount, 5, logFlags);
// TODO use compute workloads? Separate transfer-only DMA queue?
if (_queue_family == -1 && (family.queueFlags & vk::QueueFlagBits::eGraphics) && presentationSupported) {
_queue_family = i;
}
}
if (_queue_family == -1) {
J2dRlsTrace(J2D_TRACE_INFO, " No suitable queue\n");
return;
}
// Populate maps and log supported layers & extensions.
std::set<std::string> layers, extensions;
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device layers:\n");
for (auto& l : handle.enumerateDeviceLayerProperties()) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) l.layerName);
layers.emplace((char*) l.layerName);
}
J2dRlsTrace(J2D_TRACE_VERBOSE, " Supported device extensions:\n");
for (auto& e : handle.enumerateDeviceExtensionProperties(nullptr)) {
J2dRlsTrace1(J2D_TRACE_VERBOSE, " %s\n", (char*) e.extensionName);
extensions.emplace((char*) e.extensionName);
}
// Check required layers & extensions.
_enabled_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
bool requiredNotFound = false;
for (auto e : _enabled_extensions) {
if (extensions.find(e) == extensions.end()) {
J2dRlsTrace1(J2D_TRACE_INFO, " Required device extension not supported: %s\n", (char*) e);
requiredNotFound = true;
}
}
if (requiredNotFound) return;
_ext_memory_budget = extensions.find(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) != extensions.end();
if (_ext_memory_budget) _enabled_extensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
_khr_synchronization2 = extensions.find(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME) != extensions.end();
if (_khr_synchronization2) _enabled_extensions.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
_khr_dynamic_rendering = extensions.find(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME) != extensions.end();
if (_khr_dynamic_rendering) _enabled_extensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
// Validation layer
#ifdef DEBUG
if (layers.find(VALIDATION_LAYER_NAME) != layers.end()) {
_enabled_layers.push_back(VALIDATION_LAYER_NAME);
} else {
J2dRlsTrace1(J2D_TRACE_INFO, " %s device layer is not supported\n", VALIDATION_LAYER_NAME);
}
#endif
// This device is supported
((vk::raii::PhysicalDevice&) *this) = std::move(handle);
}
void VKDevice::init() {
float queuePriorities[1] {1.0f}; // We only use one queue for now
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
queueCreateInfos.push_back(vk::DeviceQueueCreateInfo {
{}, (uint32_t) physicalDevice.queue_family(), 1, &queuePriorities[0]
{}, queue_family(), 1, &queuePriorities[0]
});
vk::PhysicalDeviceFeatures features10;
features10.logicOp = true;
vk::PhysicalDeviceVulkan12Features features12;
features12.timelineSemaphore = true;
void *pNext = &features12;
vk::PhysicalDeviceSynchronization2FeaturesKHR synchronization2Features;
if (_khr_synchronization2) {
synchronization2Features.synchronization2 = true;
synchronization2Features.pNext = pNext;
pNext = &synchronization2Features;
}
vk::PhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeatures;
if (_khr_dynamic_rendering) {
dynamicRenderingFeatures.dynamicRendering = true;
dynamicRenderingFeatures.pNext = pNext;
pNext = &dynamicRenderingFeatures;
}
vk::DeviceCreateInfo deviceCreateInfo {
/*flags*/ {},
/*pQueueCreateInfos*/ queueCreateInfos,
/*ppEnabledLayerNames*/ physicalDevice.enabled_layers(),
/*ppEnabledExtensionNames*/ physicalDevice.enabled_extensions(),
/*pEnabledFeatures*/ nullptr
/*ppEnabledLayerNames*/ _enabled_layers,
/*ppEnabledExtensionNames*/ _enabled_extensions,
/*pEnabledFeatures*/ &features10,
/*pNext*/ pNext
};
*((vk::raii::Device*) this) = {physicalDevice, deviceCreateInfo};
this->_queue_family = physicalDevice.queue_family();
J2dRlsTrace(J2D_TRACE_INFO, "Vulkan: Device created\n"); // TODO which one?
((vk::raii::Device&) *this) = {*this, deviceCreateInfo};
_memory.init(_instance, *this, *this, REQUIRED_VULKAN_VERSION, _ext_memory_budget);
_pipelines.init((vk::raii::Device&) *this, _khr_dynamic_rendering);
_queue = getQueue(queue_family(), 0);
_commandPool = createCommandPool(vk::CommandPoolCreateInfo {
vk::CommandPoolCreateFlagBits::eTransient | vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
queue_family()
});
vk::SemaphoreTypeCreateInfo semaphoreTypeCreateInfo { vk::SemaphoreType::eTimeline, 0 };
_timelineSemaphore = createSemaphore(vk::SemaphoreCreateInfo {{}, &semaphoreTypeCreateInfo});
_timelineCounter = 0;
J2dRlsTrace1(J2D_TRACE_INFO, "Vulkan: Device created %s\n", _name.c_str());
}
extern "C" jint VK_MaxTextureSize() {
return (jint)VKGraphicsEnvironment::graphics_environment()->max_texture_size();
VKBuffer VKDevice::getVertexBuffer() {
auto b = popPending<VKBuffer>(_pendingVertexBuffers);
if (*b) {
b.position() = 0;
return b;
} else {
return _memory.allocateBuffer(64 * 1024, vk::BufferUsageFlagBits::eVertexBuffer,
vma::AllocationCreateFlagBits::eMapped | vma::AllocationCreateFlagBits::eHostAccessSequentialWrite,
vma::MemoryUsage::eAutoPreferHost);
}
}
extern "C" jboolean VK_Init() {
vk::raii::CommandBuffer VKDevice::getCommandBuffer(vk::CommandBufferLevel level) {
auto b = popPending<vk::raii::CommandBuffer>(level == vk::CommandBufferLevel::ePrimary ?
_pendingPrimaryBuffers : _pendingSecondaryBuffers);
if (*b) {
b.reset({});
return b;
} else {
return std::move(allocateCommandBuffers({*_commandPool, level, 1})[0]);
}
}
void VKDevice::submitCommandBuffer(vk::raii::CommandBuffer&& primary,
std::vector<vk::raii::CommandBuffer>& secondary,
std::vector<VKBuffer>& vertexBuffers,
std::vector<vk::Semaphore>& waitSemaphores,
std::vector<vk::PipelineStageFlags>& waitStages,
std::vector<vk::Semaphore>& signalSemaphores) {
_timelineCounter++;
signalSemaphores.insert(signalSemaphores.begin(), *_timelineSemaphore);
vk::TimelineSemaphoreSubmitInfo timelineInfo { 0, nullptr, (uint32_t) signalSemaphores.size(), &_timelineCounter };
queue().submit(vk::SubmitInfo {
waitSemaphores, waitStages, *primary, signalSemaphores, &timelineInfo
}, nullptr);
pushPending(_pendingPrimaryBuffers, std::move(primary));
pushPending(_pendingSecondaryBuffers, secondary);
pushPending(_pendingVertexBuffers, vertexBuffers);
signalSemaphores.clear();
waitSemaphores.clear();
waitStages.clear();
}
extern "C" jboolean VK_Init(jboolean verbose, jint requestedDevice) {
VKGraphicsEnvironment::set_verbose(verbose);
VKGraphicsEnvironment::set_requested_device(requestedDevice);
if (VKGraphicsEnvironment::graphics_environment() != nullptr) {
return true;
}
#if defined(DEBUG)
debugMessenger = nullptr;
#endif
return false;
}
}
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
VKGraphicsEnvironment::dispose();
}

View File

@@ -31,86 +31,132 @@
#define VK_NO_PROTOTYPES
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
#include <queue>
#include <vulkan/vulkan_raii.hpp>
#include "jni.h"
#include "VKMemory.h"
#include "VKPipeline.h"
class PhysicalDevice;
class VKGraphicsEnvironment;
class VKDevice : public vk::raii::Device {
class VKDevice : public vk::raii::Device, public vk::raii::PhysicalDevice {
friend class VKGraphicsEnvironment;
vk::raii::CommandPool _command_pool;
int _queue_family = -1;
VKDevice(PhysicalDevice& physicalDevice);
vk::Instance _instance;
std::string _name;
std::vector<const char*> _enabled_layers, _enabled_extensions;
bool _ext_memory_budget, _khr_synchronization2, _khr_dynamic_rendering;
int _queue_family = -1;
// Logical device state
VKMemory _memory;
VKPipelines _pipelines;
vk::raii::Queue _queue = nullptr;
vk::raii::CommandPool _commandPool = nullptr;
vk::raii::Semaphore _timelineSemaphore = nullptr;
uint64_t _timelineCounter = 0;
uint64_t _lastReadTimelineCounter = 0;
template <typename T> struct Pending {
T resource;
uint64_t counter;
using Queue = std::queue<Pending<T>>;
};
Pending<vk::raii::CommandBuffer>::Queue _pendingPrimaryBuffers, _pendingSecondaryBuffers;
Pending<VKBuffer>::Queue _pendingVertexBuffers;
template <typename T> T popPending(typename Pending<T>::Queue& queue) {
if (!queue.empty()) {
auto& f = queue.front();
if (_lastReadTimelineCounter >= f.counter ||
(_lastReadTimelineCounter = _timelineSemaphore.getCounterValue()) >= f.counter) {
T resource = std::move(f.resource);
queue.pop();
return resource;
}
}
return T(nullptr);
}
template <typename T> void pushPending(typename Pending<T>::Queue& queue, T&& resource) {
queue.push({std::move(resource), _timelineCounter});
}
template <typename T> void pushPending(typename Pending<T>::Queue& queue, std::vector<T>& resources) {
for (T& r : resources) {
pushPending(queue, std::move(r));
}
resources.clear();
}
explicit VKDevice(vk::Instance instance, vk::raii::PhysicalDevice&& handle);
public:
int queue_family() const {
return _queue_family;
bool synchronization2() {
return _khr_synchronization2;
}
bool dynamicRendering() {
return _khr_dynamic_rendering;
}
VKPipelines& pipelines() {
return _pipelines;
}
uint32_t queue_family() const {
return (uint32_t) _queue_family;
}
const vk::raii::Queue& queue() const {
return _queue;
}
void init(); // Creates actual logical device
VKBuffer getVertexBuffer();
vk::raii::CommandBuffer getCommandBuffer(vk::CommandBufferLevel level);
void submitCommandBuffer(vk::raii::CommandBuffer&& primary,
std::vector<vk::raii::CommandBuffer>& secondary,
std::vector<VKBuffer>& vertexBuffers,
std::vector<vk::Semaphore>& waitSemaphores,
std::vector<vk::PipelineStageFlags>& waitStages,
std::vector<vk::Semaphore>& signalSemaphores);
bool supported() const { // Supported or not
return *((const vk::raii::PhysicalDevice&) *this);
}
explicit operator bool() const { // Initialized or not
return *((const vk::raii::Device&) *this);
}
const std::string& name() {
return _name;
}
};
class VKSurfaceData {
uint32_t _width;
uint32_t _height;
uint32_t _scale;
uint32_t _bg_color;
public:
VKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
: _width(w), _height(h), _scale(s), _bg_color(bgc) {};
uint32_t width() const {
return _width;
}
uint32_t height() const {
return _height;
}
uint32_t scale() const {
return _scale;
}
uint32_t bg_color() const {
return _bg_color;
}
virtual void set_bg_color(uint32_t bg_color) {
_bg_color = bg_color;
}
virtual ~VKSurfaceData() = default;
virtual void revalidate(uint32_t w, uint32_t h, uint32_t s)
{
_width = w;
_height = h;
_scale = s;
}
};
class VKGraphicsEnvironment {
vk::raii::Context _vk_context;
vk::raii::Instance _vk_instance;
std::vector<PhysicalDevice> _physical_devices;
std::vector<VKDevice> _devices;
int _default_physical_device;
int _default_device;
vk::raii::Context _vk_context;
vk::raii::Instance _vk_instance;
#if defined(DEBUG)
vk::raii::DebugUtilsMessengerEXT _debugMessenger = nullptr;
#endif
std::vector<std::unique_ptr<VKDevice>> _devices;
VKDevice* _default_device;
static bool _verbose;
static int _requested_device_number;
static std::unique_ptr<VKGraphicsEnvironment> _ge_instance;
VKGraphicsEnvironment();
public:
static void set_verbose(bool verbose) { _verbose = verbose; }
static void set_requested_device(int requested_device) { _requested_device_number = requested_device; }
static VKGraphicsEnvironment* graphics_environment();
static void dispose();
VKDevice& default_device();
vk::raii::Instance& vk_instance();
uint32_t max_texture_size();
};
extern "C" {
#endif //__cplusplus
jboolean VK_Init();
jint VK_MaxTextureSize();
jboolean VK_Init(jboolean verbose, jint requestedDevice);
#ifdef __cplusplus
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#define VMA_IMPLEMENTATION
#include "VKMemory.h"
void VKMemory::init(vk::Instance instance, const vk::raii::PhysicalDevice& physicalDevice,
const vk::raii::Device& device, uint32_t apiVersion, bool extMemoryBudget) {
vma::VulkanFunctions functions = vma::functionsFromDispatcher(physicalDevice.getDispatcher(), device.getDispatcher());
vma::AllocatorCreateInfo createInfo {};
createInfo.instance = instance;
createInfo.physicalDevice = *physicalDevice;
createInfo.device = *device;
createInfo.pVulkanFunctions = &functions;
createInfo.vulkanApiVersion = apiVersion;
if (extMemoryBudget) {
createInfo.flags |= vma::AllocatorCreateFlagBits::eExtMemoryBudget;
}
_allocator = vma::createAllocatorUnique(createInfo);
*((vma::Allocator*) this) = *_allocator;
}
VKBuffer VKMemory::allocateBuffer(uint32_t size, vk::BufferUsageFlags usage,
vma::AllocationCreateFlags flags, vma::MemoryUsage memoryUsage) {
VKBuffer b = nullptr;
auto pair = createBufferUnique(vk::BufferCreateInfo {
{}, size, usage, vk::SharingMode::eExclusive, {}
}, vma::AllocationCreateInfo {
flags,
memoryUsage, {}, {}, (uint32_t) -1
}, b._allocationInfo);
b._buffer = std::move(pair.first);
b._allocation = std::move(pair.second);
b._size = size;
return b;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef VKMemory_h_Included
#define VKMemory_h_Included
#define VK_NO_PROTOTYPES
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
#include <vulkan/vulkan_raii.hpp>
#include <vk_mem_alloc.hpp>
class VKBuffer {
friend class VKMemory;
vma::UniqueBuffer _buffer;
vma::UniqueAllocation _allocation;
vma::AllocationInfo _allocationInfo;
uint32_t _size = 0;
uint32_t _position = 0;
public:
VKBuffer(nullptr_t) {}
vk::Buffer operator*() const {
return *_buffer;
}
uint32_t size() const {
return _size;
}
uint32_t& position() {
return _position;
}
void* data() {
return _allocationInfo.pMappedData;
}
};
class VKMemory : vma::Allocator {
vma::UniqueAllocator _allocator;
public:
void init(vk::Instance instance, const vk::raii::PhysicalDevice& physicalDevice,
const vk::raii::Device& device, uint32_t apiVersion, bool extMemoryBudget);
VKBuffer allocateBuffer(uint32_t size, vk::BufferUsageFlags usage,
vma::AllocationCreateFlags flags, vma::MemoryUsage memoryUsage);
};
#endif //VKMemory_h_Included

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "VKPipeline.h"
void VKPipelines::init(const vk::raii::Device& device, bool dynamicRendering) {
shaders.init(device);
vk::Format format = vk::Format::eB8G8R8A8Unorm; // TODO
if (!dynamicRendering) {
vk::AttachmentDescription attachmentDescription {
/*flags*/ {},
/*format*/ format,
/*samples*/ vk::SampleCountFlagBits::e1,
/*loadOp*/ vk::AttachmentLoadOp::eLoad,
/*storeOp*/ vk::AttachmentStoreOp::eStore,
/*stencilLoadOp*/ vk::AttachmentLoadOp::eDontCare,
/*stencilStoreOp*/ vk::AttachmentStoreOp::eDontCare,
/*initialLayout*/ vk::ImageLayout::eColorAttachmentOptimal,
/*finalLayout*/ vk::ImageLayout::eColorAttachmentOptimal
};
vk::AttachmentReference attachmentReference { 0, vk::ImageLayout::eColorAttachmentOptimal };
vk::SubpassDescription subpassDescription {
/*flags*/ {},
/*pipelineBindPoint*/ vk::PipelineBindPoint::eGraphics,
/*inputAttachmentCount*/ 0,
/*pInputAttachments*/ nullptr,
/*colorAttachmentCount*/ 1,
/*pColorAttachments*/ &attachmentReference,
/*pResolveAttachments*/ nullptr,
/*pDepthStencilAttachment*/ nullptr,
/*preserveAttachmentCount*/ 0,
/*pPreserveAttachments*/ nullptr,
};
// We don't know in advance, which operations to synchronize
// with before and after the render pass, so do a full sync.
std::array<vk::SubpassDependency, 2> subpassDependencies {vk::SubpassDependency{
/*srcSubpass*/ VK_SUBPASS_EXTERNAL,
/*dstSubpass*/ 0,
/*srcStageMask*/ vk::PipelineStageFlagBits::eBottomOfPipe,
/*dstStageMask*/ vk::PipelineStageFlagBits::eColorAttachmentOutput,
/*srcAccessMask*/ {},
/*dstAccessMask*/ vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite,
/*dependencyFlags*/ {},
}, vk::SubpassDependency{
/*srcSubpass*/ 0,
/*dstSubpass*/ VK_SUBPASS_EXTERNAL,
/*srcStageMask*/ vk::PipelineStageFlagBits::eColorAttachmentOutput,
/*dstStageMask*/ vk::PipelineStageFlagBits::eTopOfPipe,
/*srcAccessMask*/ vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite,
/*dstAccessMask*/ {},
/*dependencyFlags*/ {},
}};
renderPass = device.createRenderPass(vk::RenderPassCreateInfo{
/*flags*/ {},
/*pAttachments*/ attachmentDescription,
/*pSubpasses*/ subpassDescription,
/*pDependencies*/ subpassDependencies
});
}
vk::PushConstantRange pushConstantRange {vk::ShaderStageFlagBits::eVertex, 0, sizeof(float) * 2};
testLayout = device.createPipelineLayout(vk::PipelineLayoutCreateInfo {{}, {}, pushConstantRange});
std::array<vk::PipelineShaderStageCreateInfo, 2> testStages {shaders.test_vert.stage(), shaders.test_frag.stage()};
vk::VertexInputBindingDescription vertexInputBindingDescription {0, 8, vk::VertexInputRate::eVertex};
vk::VertexInputAttributeDescription vertexInputAttributeDescription {0, 0, vk::Format::eR32G32Sfloat, 0};
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo {{}, vertexInputBindingDescription, vertexInputAttributeDescription};
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo {{}, vk::PrimitiveTopology::eTriangleFan, false};
vk::Viewport viewport;
vk::Rect2D scissor;
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo {{}, viewport, scissor};
vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo {
{}, false, false, vk::PolygonMode::eFill, vk::CullModeFlagBits::eNone,
vk::FrontFace::eClockwise, false, 0, 0, 0, 1
};
vk::PipelineMultisampleStateCreateInfo multisampleStateCreateInfo {};
vk::PipelineColorBlendAttachmentState colorBlendAttachmentState {false}; // TODO No blending yet
colorBlendAttachmentState.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
vk::PipelineColorBlendStateCreateInfo colorBlendStateCreateInfo {{}, false, vk::LogicOp::eXor, colorBlendAttachmentState};
std::array<vk::DynamicState, 2> dynamicStates {vk::DynamicState::eViewport, vk::DynamicState::eScissor};
vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo {{}, dynamicStates};
vk::PipelineRenderingCreateInfoKHR renderingCreateInfo {0, format};
auto pipelines = device.createGraphicsPipelines(nullptr, {
vk::GraphicsPipelineCreateInfo {
{}, testStages,
&vertexInputStateCreateInfo,
&inputAssemblyStateCreateInfo,
nullptr,
&viewportStateCreateInfo,
&rasterizationStateCreateInfo,
&multisampleStateCreateInfo,
nullptr,
&colorBlendStateCreateInfo,
&dynamicStateCreateInfo,
*testLayout,
*renderPass, 0, nullptr, 0,
dynamicRendering ? &renderingCreateInfo : nullptr
}
});
// TODO pipeline cache
test = std::move(pipelines[0]);
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef VKPipeline_h_Included
#define VKPipeline_h_Included
#include "VKShader.h"
struct VKPipelines {
VKShaders shaders;
// TODO we need a pool of pipelines and (optionally) render passes for different formats.
vk::raii::RenderPass renderPass = nullptr; // Render pass is only needed if dynamic rendering is off.
vk::raii::PipelineLayout testLayout = nullptr;
vk::raii::Pipeline test = nullptr;
void init(const vk::raii::Device& device, bool dynamicRendering);
};
#endif //VKPipeline_h_Included

View File

@@ -26,8 +26,6 @@
#ifndef HEADLESS
#include <stdlib.h>
#include "sun_java2d_pipe_BufferedOpCodes.h"
#include "sun_java2d_pipe_BufferedRenderPipe.h"
#include "sun_java2d_pipe_BufferedTextPipe.h"
@@ -35,6 +33,7 @@
#include "Trace.h"
#include "jlong.h"
#include "VKRenderQueue.h"
#include "VKRenderer.h"
#define BYTES_PER_POLY_POINT \
sun_java2d_pipe_BufferedRenderPipe_BYTES_PER_POLY_POINT
@@ -62,12 +61,13 @@
#define OFFSET_XFORM sun_java2d_vulkan_VKBlitLoops_OFFSET_XFORM
#define OFFSET_ISOBLIT sun_java2d_vulkan_VKBlitLoops_OFFSET_ISOBLIT
static VKRenderer renderer;
extern "C" JNIEXPORT void JNICALL
Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
(JNIEnv *env, jobject oglrq,
jlong buf, jint limit)
{
jboolean sync = JNI_FALSE;
unsigned char *b, *end;
J2dTraceLn1(J2D_TRACE_INFO,
@@ -87,7 +87,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
while (b < end) {
jint opcode = NEXT_INT(b);
J2dRlsTraceLn2(J2D_TRACE_VERBOSE,
J2dRlsTraceLn2(J2D_TRACE_VERBOSE2,
"VKRenderQueue_flushBuffer: opcode=%d, rem=%d",
opcode, (end-b));
@@ -103,6 +103,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DRAW_LINE(%d, %d, %d, %d)",
x1, y1, x2, y2);
renderer.drawLine(x1, y1, x2, y2);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
@@ -114,6 +115,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DRAW_RECT(%d, %d, %d, %d)",
x, y, w, h);
renderer.drawRect(x, y, w, h);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:
@@ -125,8 +127,8 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint *xPoints = (jint *)b;
jint *yPoints = ((jint *)b) + nPoints;
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_POLY");
SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT);
renderer.drawPoly();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:
@@ -134,6 +136,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint x = NEXT_INT(b);
jint y = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_PIXEL");
renderer.drawPixel(x, y);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
@@ -141,6 +144,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint count = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_SCANLINES");
SKIP_BYTES(b, count * BYTES_PER_SCANLINE);
renderer.drawScanlines();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
@@ -156,6 +160,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn8(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DRAW_PARALLELOGRAM(%f, %f, %f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12);
renderer.drawParallelogram(x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:
@@ -183,6 +188,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint h = NEXT_INT(b);
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_RECT(%d, %d, %d, %d)", x, y, w, h);
renderer.fillRect(x, y, w, h);
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
@@ -191,6 +197,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_SPANS");
SKIP_BYTES(b, count * BYTES_PER_SPAN);
renderer.fillSpans();
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
@@ -204,6 +211,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_PARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12);
renderer.fillParallelogram(x11, y11, dx21, dy21, dx12, dy12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:
@@ -217,6 +225,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FILL_AAPARALLELOGRAM(%f, %f, %f, %f, %f, %f)",
x11, y11, dx21, dy21, dx12, dy12);
renderer.fillAAParallelogram(x11, y11, dx21, dy21, dx12, dy12);
}
break;
@@ -247,6 +256,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
}
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: DRAW_GLYPH_LIST");
SKIP_BYTES(b, numGlyphs * bytesPerGlyph);
renderer.drawGlyphList();
}
break;
@@ -262,6 +272,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn6(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: COPY_AREA(%d, %d, %d, %d, %d, %d)",
x, y, w, h, dx, dy);
renderer.copyArea(x, y, w, h, dx, dy);
}
break;
case sun_java2d_pipe_BufferedOpCodes_BLIT:
@@ -287,6 +298,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jboolean isoblit = EXTRACT_BOOLEAN(packedParams,
OFFSET_ISOBLIT);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: BLIT");
renderer.blit();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:
@@ -301,6 +313,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong pSrc = NEXT_LONG(b);
jlong pDst = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: SURFACE_TO_SW_BLIT");
renderer.surfaceToSwBlit();
}
break;
case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:
@@ -315,6 +328,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
unsigned char *pMask = (masklen > 0) ? b : NULL;
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: MASK_FILL");
SKIP_BYTES(b, masklen);
renderer.maskFill();
}
break;
case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:
@@ -326,6 +340,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint masklen = width * height * sizeof(jint);
J2dRlsTraceLn(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: MASK_BLIT");
SKIP_BYTES(b, masklen);
renderer.maskBlit();
}
break;
@@ -339,12 +354,14 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn4(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_RECT_CLIP(%d, %d, %d, %d)",
x1, y1, x2, y2);
renderer.setRectClip(x1, y1, x2, y2);
}
break;
case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: BEGIN_SHAPE_CLIP");
renderer.beginShapeClip();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
@@ -353,18 +370,21 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_SHAPE_CLIP_SPANS");
SKIP_BYTES(b, count * BYTES_PER_SPAN);
renderer.setShapeClipSpans();
}
break;
case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: END_SHAPE_CLIP");
renderer.endShapeClip();
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_CLIP");
renderer.resetClip();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
@@ -374,6 +394,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint flags = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_ALPHA_COMPOSITE");
renderer.setAlphaComposite();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
@@ -381,12 +402,14 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint xorPixel = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_XOR_COMPOSITE");
renderer.setXorComposite();
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_COMPOSITE");
renderer.resetComposite();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:
@@ -399,22 +422,25 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jdouble m12 = NEXT_DOUBLE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_TRANSFORM");
renderer.setTransform(m00, m10, m01, m11, m02, m12);
}
break;
case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_TRANSFORM");
renderer.resetTransform();
}
break;
// context-related ops
case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
{
jlong pSrc = NEXT_LONG(b);
jlong pDst = NEXT_LONG(b);
VKSurfaceData* src = NEXT_SURFACE(b);
VKSurfaceData* dst = NEXT_SURFACE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_SURFACES");
renderer.setSurfaces(*src, *dst);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
@@ -422,20 +448,23 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong pConfigInfo = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_SCRATCH_SURFACE");
renderer.setScratchSurface();
}
break;
case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
{
jlong pData = NEXT_LONG(b);
VKSurfaceData* surface = NEXT_SURFACE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FLUSH_SURFACE");
renderer.flushSurface(*surface);
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
{
jlong pData = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: FLUSH_SURFACE");
"VKRenderQueue_flushBuffer: DISPOSE_SURFACE");
renderer.disposeSurface();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
@@ -443,18 +472,21 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong pConfigInfo = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISPOSE_CONFIG");
renderer.disposeConfig();
}
break;
case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: INVALIDATE_CONTEXT");
renderer.invalidateContext();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SYNC:
{
sync = JNI_TRUE;
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SYNC");
renderer.sync();
}
break;
@@ -464,11 +496,16 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jlong window = NEXT_LONG(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SWAP_BUFFERS");
renderer.swapBuffers();
}
break;
// special no-op (mainly used for achieving 8-byte alignment)
case sun_java2d_pipe_BufferedOpCodes_NOOP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: NOOP");
}
break;
// paint-related ops
@@ -476,6 +513,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: RESET_PAINT");
renderer.resetPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
@@ -483,6 +521,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint pixel = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_COLOR");
renderer.setColor((uint32_t) pixel);
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:
@@ -496,6 +535,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jint pixel2 = NEXT_INT(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_GRADIENT_PAINT");
renderer.setGradientPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:
@@ -512,6 +552,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_LINEAR_GRADIENT_PAINT");
renderer.setLinearGradientPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:
@@ -532,6 +573,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
pixels = b; SKIP_BYTES(b, numStops * sizeof(jint));
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_RADIAL_GRADIENT_PAINT");
renderer.setRadialGradientPaint();
}
break;
case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:
@@ -547,6 +589,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
jdouble yp3 = NEXT_DOUBLE(b);
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: SET_TEXTURE_PAINT");
renderer.setTexturePaint();
}
break;
@@ -560,12 +603,14 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: ENABLE_CONVOLVE_OP");
SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
renderer.enableConvolveOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISABLE_CONVOLVE_OP");
renderer.disableConvolveOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:
@@ -578,12 +623,14 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: ENABLE_RESCALE_OP");
SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
renderer.enableRescaleOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISABLE_RESCALE_OP");
renderer.disableRescaleOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:
@@ -599,12 +646,14 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: ENABLE_LOOKUP_OP");
SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
renderer.enableLookupOp();
}
break;
case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
{
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
"VKRenderQueue_flushBuffer: DISABLE_LOOKUP_OP");
renderer.disableLookupOp();
}
break;
@@ -614,6 +663,7 @@ Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer
return;
}
}
renderer.flush();
}
#endif /* !HEADLESS */

View File

@@ -38,6 +38,7 @@
#define NEXT_BOOLEAN(buf) (jboolean)NEXT_INT(buf)
#define NEXT_LONG(buf) NEXT_VAL(buf, jlong)
#define NEXT_DOUBLE(buf) NEXT_VAL(buf, jdouble)
#define NEXT_SURFACE(buf) ((VKSurfaceData*) (SurfaceDataOps*) jlong_to_ptr(NEXT_LONG(buf)))
/*
* Increments a pointer (buf) by the given number of bytes.

View File

@@ -0,0 +1,282 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "VKRenderer.h"
VKRecorder::Vertex* VKRecorder::draw(uint32_t numVertices) {
uint32_t bytes = numVertices * sizeof(VKRecorder::Vertex);
if (_renderPass.vertexBuffer == nullptr && !_vertexBuffers.empty()) {
_renderPass.vertexBuffer = &_vertexBuffers.back();
_renderPass.commandBuffer->bindVertexBuffers(0, **_renderPass.vertexBuffer, vk::DeviceSize(0));
}
if (_renderPass.vertexBuffer == nullptr ||
_renderPass.vertexBuffer->position() + bytes > _renderPass.vertexBuffer->size()) {
_vertexBuffers.push_back(device().getVertexBuffer());
_renderPass.vertexBuffer = &_vertexBuffers.back(); // TODO check that our number of vertices fit into single buffer at all
_renderPass.commandBuffer->bindVertexBuffers(0, **_renderPass.vertexBuffer, vk::DeviceSize(0));
}
auto data = (uintptr_t) _renderPass.vertexBuffer->data() + _renderPass.vertexBuffer->position();
uint32_t firstVertex = _renderPass.vertexBuffer->position() / sizeof(VKRecorder::Vertex);
_renderPass.vertexBuffer->position() += bytes;
_renderPass.commandBuffer->draw(numVertices, 1, firstVertex, 0);
return (VKRecorder::Vertex*) data;
}
VKDevice* VKRecorder::setDevice(VKDevice *device) {
if (device != _device) {
if (_device != nullptr) {
flush();
}
std::swap(_device, device);
}
return device;
}
void VKRecorder::waitSemaphore(vk::Semaphore semaphore, vk::PipelineStageFlags stage) {
_waitSemaphores.push_back(semaphore);
_waitSemaphoreStages.push_back(stage);
}
void VKRecorder::signalSemaphore(vk::Semaphore semaphore) {
_signalSemaphores.push_back(semaphore);
}
const vk::raii::CommandBuffer& VKRecorder::record(bool flushRenderPass) {
if (!*_commandBuffer) {
_commandBuffer = device().getCommandBuffer(vk::CommandBufferLevel::ePrimary);
_commandBuffer.begin({vk::CommandBufferUsageFlagBits::eOneTimeSubmit });
}
if (flushRenderPass && _renderPass.commandBuffer != nullptr) {
_renderPass.commandBuffer->end();
vk::Rect2D renderArea {{0, 0}, {_renderPass.surface->width(), _renderPass.surface->height()}};
if (device().dynamicRendering()) {
vk::RenderingAttachmentInfoKHR colorAttachmentInfo {
_renderPass.surfaceView, vk::ImageLayout::eColorAttachmentOptimal,
vk::ResolveModeFlagBits::eNone, {}, {},
_renderPass.attachmentLoadOp, vk::AttachmentStoreOp::eStore,
_renderPass.clearValue
};
_commandBuffer.beginRenderingKHR(vk::RenderingInfoKHR{
vk::RenderingFlagBitsKHR::eContentsSecondaryCommandBuffers,
renderArea, 1, 0, colorAttachmentInfo, {}, {}
});
} else {
_commandBuffer.beginRenderPass(vk::RenderPassBeginInfo{
/*renderPass*/ *device().pipelines().renderPass,
/*framebuffer*/ _renderPass.surfaceFramebuffer,
/*renderArea*/ renderArea,
/*clearValueCount*/ 0,
/*pClearValues*/ nullptr
}, vk::SubpassContents::eSecondaryCommandBuffers);
}
_commandBuffer.executeCommands(**_renderPass.commandBuffer);
if (device().dynamicRendering()) {
_commandBuffer.endRenderingKHR();
} else {
_commandBuffer.endRenderPass();
}
_renderPass = {};
}
return _commandBuffer;
}
const vk::raii::CommandBuffer& VKRecorder::render(VKSurfaceData& surface, vk::ClearColorValue* clear) {
if (_renderPass.surface != &surface) {
if (_renderPass.commandBuffer != nullptr) {
record(true); // Flush current render pass
}
VKSurfaceImage i = surface.access(*this,
vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::AccessFlagBits::eColorAttachmentWrite,
vk::ImageLayout::eColorAttachmentOptimal);
_renderPass.surface = &surface;
_renderPass.surfaceView = i.view;
_renderPass.surfaceFramebuffer = i.framebuffer;
_renderPass.attachmentLoadOp = vk::AttachmentLoadOp::eLoad;
}
if (clear != nullptr) {
_renderPass.clearValue = *clear;
_renderPass.attachmentLoadOp = vk::AttachmentLoadOp::eClear;
}
if (_renderPass.commandBuffer == nullptr || clear != nullptr) {
if (_renderPass.commandBuffer == nullptr) {
_secondaryBuffers.push_back(device().getCommandBuffer(vk::CommandBufferLevel::eSecondary));
_renderPass.commandBuffer = &_secondaryBuffers.back();
} else {
// We already recorded some rendering commands, but it doesn't matter, as we'll clear the surface anyway.
_renderPass.commandBuffer->reset({});
}
vk::Format format = surface.format();
vk::CommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo {
vk::RenderingFlagBitsKHR::eContentsSecondaryCommandBuffers,
0, format
};
vk::CommandBufferInheritanceInfo inheritanceInfo;
if (device().dynamicRendering()) {
inheritanceInfo.pNext = &inheritanceRenderingInfo;
} else {
inheritanceInfo.renderPass = *device().pipelines().renderPass;
inheritanceInfo.subpass = 0;
inheritanceInfo.framebuffer = _renderPass.surfaceFramebuffer;
}
_renderPass.commandBuffer->begin({ vk::CommandBufferUsageFlagBits::eOneTimeSubmit |
vk::CommandBufferUsageFlagBits::eRenderPassContinue, &inheritanceInfo });
if (clear != nullptr && !device().dynamicRendering()) {
// Our static render pass uses loadOp=LOAD, so clear attachment manually.
_renderPass.commandBuffer->clearAttachments(vk::ClearAttachment {
vk::ImageAspectFlagBits::eColor, 0, _renderPass.clearValue
}, vk::ClearRect {vk::Rect2D{{0, 0}, {_renderPass.surface->width(), _renderPass.surface->height()}}, 0, 1});
}
}
return *_renderPass.commandBuffer;
}
void VKRecorder::flush() {
if (!*_commandBuffer && _renderPass.commandBuffer == nullptr) {
return;
}
record(true).end();
device().submitCommandBuffer(std::move(_commandBuffer), _secondaryBuffers, _vertexBuffers,
_waitSemaphores, _waitSemaphoreStages, _signalSemaphores);
}
// draw ops
void VKRenderer::drawLine(jint x1, jint y1, jint x2, jint y2) {/*TODO*/}
void VKRenderer::drawRect(jint x, jint y, jint w, jint h) {/*TODO*/}
void VKRenderer::drawPoly(/*TODO*/) {/*TODO*/}
void VKRenderer::drawPixel(jint x, jint y) {/*TODO*/}
void VKRenderer::drawScanlines(/*TODO*/) {/*TODO*/}
void VKRenderer::drawParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12) {/*TODO*/}
void VKRenderer::drawAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12) {/*TODO*/}
// fill ops
void VKRenderer::fillRect(jint xi, jint yi, jint wi, jint hi) {
// TODO
auto& cb = render(*_dstSurface);
// cb.clearAttachments(vk::ClearAttachment {vk::ImageAspectFlagBits::eColor, 0, _color},
// vk::ClearRect {vk::Rect2D {{x, y}, {(uint32_t) w, (uint32_t) h}}, 0, 1});
cb.bindPipeline(vk::PipelineBindPoint::eGraphics, *device().pipelines().test);
cb.pushConstants<float>(*device().pipelines().testLayout, vk::ShaderStageFlagBits::eVertex, 0, {
2.0f/(float)_dstSurface->width(), 2.0f/(float)_dstSurface->height()
});
vk::Viewport viewport {0, 0, (float) _dstSurface->width(), (float) _dstSurface->height(), 0, 1};
cb.setViewport(0, viewport);
vk::Rect2D scissor {{0, 0}, {_dstSurface->width(), _dstSurface->height()}};
cb.setScissor(0, scissor);
auto x = (float) xi, y = (float) yi, w = (float) wi, h = (float) hi;
auto v = draw(4);
v[0] = {x, y};
v[1] = {x+w, y};
v[2] = {x+w, y+h};
v[3] = {x, y+h};
}
void VKRenderer::fillSpans(/*TODO*/) {/*TODO*/}
void VKRenderer::fillParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12) {/*TODO*/}
void VKRenderer::fillAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12) {/*TODO*/}
// text-related ops
void VKRenderer::drawGlyphList(/*TODO*/) {/*TODO*/}
// copy-related ops
void VKRenderer::copyArea(jint x, jint y, jint w, jint h, jint dx, jint dy) {/*TODO*/}
void VKRenderer::blit(/*TODO*/) {/*TODO*/}
void VKRenderer::surfaceToSwBlit(/*TODO*/) {/*TODO*/}
void VKRenderer::maskFill(/*TODO*/) {/*TODO*/}
void VKRenderer::maskBlit(/*TODO*/) {/*TODO*/}
// state-related ops
void VKRenderer::setRectClip(jint x1, jint y1, jint x2, jint y2) {/*TODO*/}
void VKRenderer::beginShapeClip() {/*TODO*/}
void VKRenderer::setShapeClipSpans(/*TODO*/) {/*TODO*/}
void VKRenderer::endShapeClip() {/*TODO*/}
void VKRenderer::resetClip() {/*TODO*/}
void VKRenderer::setAlphaComposite(/*TODO*/) {/*TODO*/}
void VKRenderer::setXorComposite(/*TODO*/) {/*TODO*/}
void VKRenderer::resetComposite() {/*TODO*/}
void VKRenderer::setTransform(jdouble m00, jdouble m10,
jdouble m01, jdouble m11,
jdouble m02, jdouble m12) {/*TODO*/}
void VKRenderer::resetTransform() {/*TODO*/}
// context-related ops
void VKRenderer::setSurfaces(VKSurfaceData& src, VKSurfaceData& dst) {
if (&src.device() != &dst.device()) {
throw std::runtime_error("src and dst surfaces use different devices!");
}
setDevice(&dst.device());
_dstSurface = &dst;
_srcSurface = &src;
}
void VKRenderer::setScratchSurface(/*TODO*/) {/*TODO*/}
void VKRenderer::flushSurface(VKSurfaceData& surface) {
VKDevice* old = setDevice(&surface.device());
surface.flush(*this);
setDevice(old);
}
void VKRenderer::disposeSurface(/*TODO*/) {/*TODO*/}
void VKRenderer::disposeConfig(/*TODO*/) {/*TODO*/}
void VKRenderer::invalidateContext() {/*TODO*/}
void VKRenderer::sync() {/*TODO*/}
// multibuffering ops
void VKRenderer::swapBuffers(/*TODO*/) {/*TODO*/}
// paint-related ops
void VKRenderer::resetPaint() {/*TODO*/}
void VKRenderer::setColor(uint32_t pixel) {
_color = pixel;
}
void VKRenderer::setGradientPaint(/*TODO*/) {/*TODO*/}
void VKRenderer::setLinearGradientPaint(/*TODO*/) {/*TODO*/}
void VKRenderer::setRadialGradientPaint(/*TODO*/) {/*TODO*/}
void VKRenderer::setTexturePaint(/*TODO*/) {/*TODO*/}
// BufferedImageOp-related ops
void VKRenderer::enableConvolveOp(/*TODO*/) {/*TODO*/}
void VKRenderer::disableConvolveOp() {/*TODO*/}
void VKRenderer::enableRescaleOp(/*TODO*/) {/*TODO*/}
void VKRenderer::disableRescaleOp() {/*TODO*/}
void VKRenderer::enableLookupOp() {/*TODO*/}
void VKRenderer::disableLookupOp() {/*TODO*/}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef VKRenderer_h_Included
#define VKRenderer_h_Included
#ifdef __cplusplus
#include "VKBase.h"
#include "VKSurfaceData.h"
class VKRecorder{
VKDevice *_device;
vk::raii::CommandBuffer _commandBuffer = nullptr;
std::vector<vk::raii::CommandBuffer> _secondaryBuffers;
std::vector<vk::Semaphore> _waitSemaphores, _signalSemaphores;
std::vector<vk::PipelineStageFlags> _waitSemaphoreStages;
std::vector<VKBuffer> _vertexBuffers;
struct RenderPass {
vk::raii::CommandBuffer *commandBuffer = nullptr;
VKSurfaceData *surface = nullptr;
VKBuffer *vertexBuffer = nullptr;
vk::ImageView surfaceView;
vk::Framebuffer surfaceFramebuffer; // Only if dynamic rendering is off.
vk::AttachmentLoadOp attachmentLoadOp;
vk::ClearValue clearValue;
} _renderPass {};
protected:
struct Vertex {
float x, y;
};
Vertex* draw(uint32_t numVertices);
VKDevice& device() {
return *_device;
}
VKDevice* setDevice(VKDevice *device);
public:
void waitSemaphore(vk::Semaphore semaphore, vk::PipelineStageFlags stage);
void signalSemaphore(vk::Semaphore semaphore);
const vk::raii::CommandBuffer& record(bool flushRenderPass = true); // Prepare for ordinary commands
const vk::raii::CommandBuffer& render(VKSurfaceData& surface,
vk::ClearColorValue* clear = nullptr); // Prepare for render pass commands
void flush();
};
class VKRenderer : private VKRecorder{
VKSurfaceData *_srcSurface, *_dstSurface;
struct alignas(16) Color {
float r, g, b, a;
Color& operator=(uint32_t c) {
r = (float) ((c >> 16) & 0xff) / 255.0f;
g = (float) ((c >> 8) & 0xff) / 255.0f;
b = (float) (c & 0xff) / 255.0f;
a = (float) ((c >> 24) & 0xff) / 255.0f;
return *this;
}
operator vk::ClearValue() const {
return vk::ClearColorValue {r, g, b, a};
}
} _color;
public:
using VKRecorder::flush;
// draw ops
void drawLine(jint x1, jint y1, jint x2, jint y2);
void drawRect(jint x, jint y, jint w, jint h);
void drawPoly(/*TODO*/);
void drawPixel(jint x, jint y);
void drawScanlines(/*TODO*/);
void drawParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12);
void drawAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12,
jfloat lwr21, jfloat lwr12);
// fill ops
void fillRect(jint x, jint y, jint w, jint h);
void fillSpans(/*TODO*/);
void fillParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
void fillAAParallelogram(jfloat x11, jfloat y11,
jfloat dx21, jfloat dy21,
jfloat dx12, jfloat dy12);
// text-related ops
void drawGlyphList(/*TODO*/);
// copy-related ops
void copyArea(jint x, jint y, jint w, jint h, jint dx, jint dy);
void blit(/*TODO*/);
void surfaceToSwBlit(/*TODO*/);
void maskFill(/*TODO*/);
void maskBlit(/*TODO*/);
// state-related ops
void setRectClip(jint x1, jint y1, jint x2, jint y2);
void beginShapeClip();
void setShapeClipSpans(/*TODO*/);
void endShapeClip();
void resetClip();
void setAlphaComposite(/*TODO*/);
void setXorComposite(/*TODO*/);
void resetComposite();
void setTransform(jdouble m00, jdouble m10,
jdouble m01, jdouble m11,
jdouble m02, jdouble m12);
void resetTransform();
// context-related ops
void setSurfaces(VKSurfaceData& src, VKSurfaceData& dst);
void setScratchSurface(/*TODO*/);
void flushSurface(VKSurfaceData& surface);
void disposeSurface(/*TODO*/);
void disposeConfig(/*TODO*/);
void invalidateContext();
void sync();
// multibuffering ops
void swapBuffers(/*TODO*/);
// paint-related ops
void resetPaint();
void setColor(uint32_t pixel);
void setGradientPaint(/*TODO*/);
void setLinearGradientPaint(/*TODO*/);
void setRadialGradientPaint(/*TODO*/);
void setTexturePaint(/*TODO*/);
// BufferedImageOp-related ops
void enableConvolveOp(/*TODO*/);
void disableConvolveOp();
void enableRescaleOp(/*TODO*/);
void disableRescaleOp();
void enableLookupOp();
void disableLookupOp();
};
#endif //__cplusplus
#endif //VKRenderer_h_Included

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "VKShader.h"
// Inline bytecode of all shaders
#define INCLUDE_BYTECODE
#define SHADER_ENTRY(NAME, TYPE) static uint32_t NAME ## _ ## TYPE ## _data[] = {
#define BYTECODE_END };
#include "vulkan/shader_list.h"
#undef INCLUDE_BYTECODE
#undef SHADER_ENTRY
#undef BYTECODE_END
void VKShaders::init(const vk::raii::Device& device) {
// Declare file extensions as stage flags
auto vert = vk::ShaderStageFlagBits::eVertex;
auto frag = vk::ShaderStageFlagBits::eFragment;
// Init all shader modules
# define SHADER_ENTRY(NAME, TYPE) \
NAME ## _ ## TYPE.init(device, sizeof NAME ## _ ## TYPE ## _data, NAME ## _ ## TYPE ## _data, TYPE);
# include "vulkan/shader_list.h"
# undef SHADER_ENTRY
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef VKShader_h_Included
#define VKShader_h_Included
#define VK_NO_PROTOTYPES
#define VULKAN_HPP_NO_DEFAULT_DISPATCHER
#include <vulkan/vulkan_raii.hpp>
class VKShader : public vk::raii::ShaderModule {
friend struct VKShaders;
vk::ShaderStageFlagBits _stage;
void init(const vk::raii::Device& device, size_t size, const uint32_t* data, vk::ShaderStageFlagBits stage) {
*((vk::raii::ShaderModule*) this) = device.createShaderModule({{}, size, data});
_stage = stage;
}
public:
VKShader() : vk::raii::ShaderModule(nullptr), _stage() {}
vk::PipelineShaderStageCreateInfo stage(const vk::SpecializationInfo *specializationInfo = nullptr) {
return vk::PipelineShaderStageCreateInfo {{}, _stage, **this, "main", specializationInfo};
}
};
struct VKShaders {
// Actual list of shaders is autogenerated from source file names
# define SHADER_ENTRY(NAME, TYPE) VKShader NAME ## _ ## TYPE;
# include "vulkan/shader_list.h"
# undef SHADER_ENTRY
void init(const vk::raii::Device& device);
};
#endif //VKShader_h_Included

View File

@@ -28,11 +28,7 @@
#ifndef VULKAN_ENABLED
#include "jni.h"
jboolean VK_Init() {
return 0;
}
jint VK_MaxTextureSize() {
jboolean VK_Init(jboolean verbose, jint requestedDevice) {
return 0;
}

View File

@@ -0,0 +1,211 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "jni_util.h"
#include "Disposer.h"
#include "Trace.h"
#include "VKSurfaceData.h"
#include "VKRenderer.h"
void VKSurfaceData::attachToJavaSurface(JNIEnv *env, jobject javaSurfaceData) {
// SurfaceData utility functions operate on C structures and malloc/free,
// But we are using C++ classes, so set up the disposer manually.
// This is a C++ analogue of SurfaceData_InitOps / SurfaceData_SetOps.
jboolean exception = false;
if (JNU_GetFieldByName(env, &exception, javaSurfaceData, "pData", "J").j == 0 && !exception) {
jlong ptr = ptr_to_jlong((SurfaceDataOps*) this);
JNU_SetFieldByName(env, &exception, javaSurfaceData, "pData", "J", ptr);
/* Register the data for disposal */
Disposer_AddRecord(env, javaSurfaceData, [](JNIEnv *env, jlong ops) {
if (ops != 0) {
auto sd = (SurfaceDataOps*)jlong_to_ptr(ops);
jobject sdObject = sd->sdObject;
sd->Dispose(env, sd);
if (sdObject != nullptr) {
env->DeleteWeakGlobalRef(sdObject);
}
}
}, ptr);
} else if (!exception) {
throw std::runtime_error("Attempting to set SurfaceData ops twice");
}
if (exception) {
throw std::runtime_error("VKSurfaceData::attachToJavaSurface error");
}
sdObject = env->NewWeakGlobalRef(javaSurfaceData);
}
VKSurfaceData::VKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
: SurfaceDataOps(), _width(w), _height(h), _scale(s), _bg_color(bgc), _device(nullptr) {
Lock = [](JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *rasInfo, jint lockFlags) {
((VKSurfaceData*) ops)->_mutex.lock();
return SD_SUCCESS;
};
Unlock = [](JNIEnv *env, SurfaceDataOps *ops, SurfaceDataRasInfo *rasInfo) {
((VKSurfaceData*) ops)->_mutex.unlock();
};
Dispose = [](JNIEnv *env, SurfaceDataOps *ops) {
delete (VKSurfaceData*) ops;
};
}
bool VKSurfaceData::barrier(VKRecorder& recorder, vk::Image image,
vk::PipelineStageFlags stage, vk::AccessFlags access, vk::ImageLayout layout) {
// TODO consider write/read access
if (_lastStage != stage || _lastAccess != access || _layout != layout) {
if (_device->synchronization2()) {
vk::ImageMemoryBarrier2KHR barrier {
(vk::PipelineStageFlags2KHR) (VkFlags) _lastStage,
(vk::AccessFlags2KHR) (VkFlags) _lastAccess,
(vk::PipelineStageFlags2KHR) (VkFlags) stage,
(vk::AccessFlags2KHR) (VkFlags) access,
_layout, layout,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
image, vk::ImageSubresourceRange {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}
};
recorder.record(false).pipelineBarrier2KHR(vk::DependencyInfoKHR {{}, {}, {}, barrier});
} else {
vk::ImageMemoryBarrier barrier {
_lastAccess, access,
_layout, layout,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
image, vk::ImageSubresourceRange {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}
};
recorder.record(false).pipelineBarrier(_lastStage, stage, {}, {}, {}, barrier);
}
_lastStage = stage;
_lastAccess = access;
_layout = layout;
// TODO check write access
return true;
} else return false;
}
void VKSwapchainSurfaceData::revalidate(uint32_t w, uint32_t h, uint32_t s) {
if (*_swapchain && s == scale() && w == width() && h == height() ) {
J2dTraceLn1(J2D_TRACE_INFO,
"VKSwapchainSurfaceData_revalidate is skipped: swapchain(%p)",
*_swapchain);
return;
}
VKSurfaceData::revalidate(w, h, s);
if (!_device || !*_surface) {
J2dTraceLn2(J2D_TRACE_ERROR,
"VKSwapchainSurfaceData_revalidate is skipped: device(%p) surface(%p)",
_device, *_surface);
return;
}
vk::SurfaceCapabilitiesKHR surfaceCapabilities = device().getSurfaceCapabilitiesKHR(*_surface);
_format = vk::Format::eB8G8R8A8Unorm; // TODO?
// TODO all these parameters must be checked against device & surface capabilities
vk::SwapchainCreateInfoKHR swapchainCreateInfo{
{},
*_surface,
surfaceCapabilities.minImageCount,
format(),
vk::ColorSpaceKHR::eVkColorspaceSrgbNonlinear,
{width(), height()}, // TODO According to spec we need to use surfaceCapabilities.currentExtent, which is not available at this point (it gives -1)... We'll figure this out later
1,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst,
vk::SharingMode::eExclusive,
0,
nullptr,
vk::SurfaceTransformFlagBitsKHR::eIdentity,
vk::CompositeAlphaFlagBitsKHR::eOpaque,
vk::PresentModeKHR::eImmediate,
true, *_swapchain
};
device().waitIdle(); // TODO proper synchronization in case there are rendering operations for old swapchain in flight
_images.clear();
_swapchain = device().createSwapchainKHR(swapchainCreateInfo);
for (vk::Image image : _swapchain.getImages()) {
_images.push_back({image, device().createImageView(vk::ImageViewCreateInfo {
{}, image, vk::ImageViewType::e2D, format(), {},
vk::ImageSubresourceRange {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}
})});
if (!device().dynamicRendering()) {
_images.back().framebuffer = device().createFramebuffer(vk::FramebufferCreateInfo{
/*flags*/ {},
/*renderPass*/ *device().pipelines().renderPass,
/*attachmentCount*/ 1,
/*pAttachments*/ &*_images.back().view,
/*width*/ width(),
/*height*/ height(),
/*layers*/ 1
});
}
}
_currentImage = (uint32_t) -1;
_freeSemaphore = nullptr;
// TODO Now we need to repaint our surface... How is it done? No idea
}
VKSurfaceImage VKSwapchainSurfaceData::access(VKRecorder& recorder,
vk::PipelineStageFlags stage,
vk::AccessFlags access,
vk::ImageLayout layout) {
// Acquire image
bool semaphorePending = false;
if (_currentImage == (uint32_t) -1) {
if (!*_freeSemaphore) {
_freeSemaphore = device().createSemaphore({});
}
auto img = _swapchain.acquireNextImage(-1, *_freeSemaphore, nullptr);
vk::resultCheck(img.first, "vk::SwapchainKHR::acquireNextImage");
_layout = vk::ImageLayout::eUndefined;
_lastStage = _lastWriteStage = vk::PipelineStageFlagBits::eTopOfPipe;
_lastAccess = _lastWriteAccess = {};
_currentImage = (int) img.second;
std::swap(_images[_currentImage].semaphore, _freeSemaphore);
semaphorePending = true;
}
// Insert barrier & semaphore
auto& current = _images[_currentImage];
barrier(recorder, current.image, stage, access, layout);
if (semaphorePending) {
recorder.waitSemaphore(*current.semaphore,
vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eTransfer);
}
return {current.image, *current.view, *current.framebuffer};
}
void VKSwapchainSurfaceData::flush(VKRecorder& recorder) {
if (_currentImage == (uint32_t) -1) {
return; // Nothing to flush
}
recorder.record(true); // Force flush current render pass before accessing image with present layout.
access(recorder, vk::PipelineStageFlagBits::eTopOfPipe, {}, vk::ImageLayout::ePresentSrcKHR);
auto& current = _images[_currentImage];
recorder.signalSemaphore(*current.semaphore);
recorder.flush();
device().queue().presentKHR(vk::PresentInfoKHR {
*current.semaphore, *_swapchain, _currentImage
});
_currentImage = (uint32_t) -1;
}

View File

@@ -27,62 +27,10 @@
#ifndef VKSurfaceData_h_Included
#define VKSurfaceData_h_Included
#include "java_awt_image_AffineTransformOp.h"
#include "sun_java2d_pipe_hw_AccelSurface.h"
#include <mutex>
#include "jni.h"
#include "SurfaceData.h"
#include "Trace.h"
/**
* The VKSDOps structure describes a native Vulkan surface and contains all
* information pertaining to the native surface. Some information about
* the more important/different fields:
*
* void *privOps;
* Pointer to native-specific SurfaceData info, such as the
* native Drawable handle and GraphicsConfig data.
*
* jobject graphicsConfig;
* Strong reference to the VKGraphicsConfig used by this VKSurfaceData.
*
* jint drawableType;
* The surface type; can be any one of the surface type constants defined
* below (VK_WINDOW, VK_TEXTURE, etc).
*
* jboolean isOpaque;
* If true, the surface should be treated as being fully opaque.
*
* jboolean needsInit;
* If true, the surface requires some one-time initialization, which should
* be performed after a context has been made current to the surface for
* the first time.
*
* jint x/yOffset
* The offset in pixels of the Vulkan viewport origin from the lower-left
* corner of the heavyweight drawable.
*
* jint width/height;
* The cached surface bounds. For offscreen surface types (VK_RT_TEXTURE,
* VK_TEXTURE, etc.) these values must remain constant. Onscreen window
* surfaces (VK_WINDOW, etc.) may have their
* bounds changed in response to a programmatic or user-initiated event, so
* these values represent the last known dimensions. To determine the true
* current bounds of this surface, query the native Drawable through the
* privOps field.
*
*/
typedef struct _VKSDOps {
SurfaceDataOps sdOps;
void *privOps;
jobject graphicsConfig;
jint drawableType;
jboolean isOpaque;
jboolean needsInit;
jint xOffset;
jint yOffset;
jint width;
jint height;
} VKSDOps;
#include "VKBase.h"
/**
* These are shorthand names for the surface type constants defined in
@@ -92,4 +40,123 @@ typedef struct _VKSDOps {
#define VKSD_WINDOW sun_java2d_pipe_hw_AccelSurface_WINDOW
#define VKSD_TEXTURE sun_java2d_pipe_hw_AccelSurface_TEXTURE
#define VKSD_RT_TEXTURE sun_java2d_pipe_hw_AccelSurface_RT_TEXTURE
class VKRecorder;
struct VKSurfaceImage {
vk::Image image;
vk::ImageView view;
vk::Framebuffer framebuffer; // Only if dynamic rendering is off.
};
class VKSurfaceData : private SurfaceDataOps {
std::recursive_mutex _mutex;
uint32_t _width;
uint32_t _height;
uint32_t _scale; // TODO Is it needed there at all?
uint32_t _bg_color;
protected:
VKDevice* _device;
vk::Format _format;
vk::ImageLayout _layout = vk::ImageLayout::eUndefined;
// We track any access and write access separately, as read-read access does not need synchronization.
vk::PipelineStageFlags _lastStage = vk::PipelineStageFlagBits::eTopOfPipe;
vk::PipelineStageFlags _lastWriteStage = vk::PipelineStageFlagBits::eTopOfPipe;
vk::AccessFlags _lastAccess = {};
vk::AccessFlags _lastWriteAccess = {};
/// Insert barrier if needed for given access and layout.
bool barrier(VKRecorder& recorder, vk::Image image,
vk::PipelineStageFlags stage, vk::AccessFlags access, vk::ImageLayout layout);
public:
VKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc);
// No need to move, as object must only be created with "new".
VKSurfaceData(VKSurfaceData&&) = delete;
VKSurfaceData& operator=(VKSurfaceData&&) = delete;
void attachToJavaSurface(JNIEnv *env, jobject javaSurfaceData);
VKDevice& device() const {
return *_device;
}
vk::Format format() const {
return _format;
}
uint32_t width() const {
return _width;
}
uint32_t height() const {
return _height;
}
uint32_t scale() const {
return _scale;
}
uint32_t bg_color() const {
return _bg_color;
}
void set_bg_color(uint32_t bg_color) {
if (_bg_color != bg_color) {
_bg_color = bg_color;
// TODO now we need to repaint the surface???
}
}
virtual ~VKSurfaceData() = default;
virtual void revalidate(uint32_t w, uint32_t h, uint32_t s) {
_width = w;
_height = h;
_scale = s;
}
/// Prepare image for access (necessary barriers & layout transitions).
virtual VKSurfaceImage access(VKRecorder& recorder,
vk::PipelineStageFlags stage,
vk::AccessFlags access,
vk::ImageLayout layout) = 0;
/// Flush all pending changes to the surface, including screen presentation for on-screen surfaces.
virtual void flush(VKRecorder& recorder) = 0;
};
class VKSwapchainSurfaceData : public VKSurfaceData {
struct Image {
vk::Image image;
vk::raii::ImageView view;
vk::raii::Framebuffer framebuffer = nullptr; // Only if dynamic rendering is off.
vk::raii::Semaphore semaphore = nullptr;
};
vk::raii::SurfaceKHR _surface = nullptr;
vk::raii::SwapchainKHR _swapchain = nullptr;
std::vector<Image> _images;
uint32_t _currentImage = (uint32_t) -1;
vk::raii::Semaphore _freeSemaphore = nullptr;
protected:
void reset(VKDevice& device, vk::raii::SurfaceKHR surface) {
_images.clear();
_swapchain = nullptr;
_surface = std::move(surface);
_device = &device;
}
public:
VKSwapchainSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
: VKSurfaceData(w, h, s, bgc) {};
virtual void revalidate(uint32_t w, uint32_t h, uint32_t s);
virtual VKSurfaceImage access(VKRecorder& recorder,
vk::PipelineStageFlags stage,
vk::AccessFlags access,
vk::ImageLayout layout);
virtual void flush(VKRecorder& recorder);
};
#endif /* VKSurfaceData_h_Included */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
#ifndef VULKAN_MEMORY_ALLOCATOR_HPP
#define VULKAN_MEMORY_ALLOCATOR_HPP
#if !defined(AMD_VULKAN_MEMORY_ALLOCATOR_H)
#include <vk_mem_alloc.h>
#endif
#include <vulkan/vulkan.hpp>
#if !defined(VMA_HPP_NAMESPACE)
#define VMA_HPP_NAMESPACE vma
#endif
#define VMA_HPP_NAMESPACE_STRING VULKAN_HPP_STRINGIFY(VMA_HPP_NAMESPACE)
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VMA_HPP_NAMESPACE {
struct Dispatcher {}; // VMA uses function pointers from VmaAllocator instead
class Allocator;
template<class T>
VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher> createUniqueHandle(const T& t) VULKAN_HPP_NOEXCEPT {
return VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>(t);
}
template<class T, class O>
VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher> createUniqueHandle(const T& t, const O* o) VULKAN_HPP_NOEXCEPT {
return VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>(t, o);
}
template<class F, class S, class O>
std::pair<VULKAN_HPP_NAMESPACE::UniqueHandle<F, Dispatcher>, VULKAN_HPP_NAMESPACE::UniqueHandle<S, Dispatcher>>
createUniqueHandle(const std::pair<F, S>& t, const O* o) VULKAN_HPP_NOEXCEPT {
return {
VULKAN_HPP_NAMESPACE::UniqueHandle<F, Dispatcher>(t.first, o),
VULKAN_HPP_NAMESPACE::UniqueHandle<S, Dispatcher>(t.second, o)
};
}
template<class T, class UniqueVectorAllocator, class VectorAllocator, class O>
std::vector<VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>, UniqueVectorAllocator>
createUniqueHandleVector(const std::vector<T, VectorAllocator>& vector, const O* o,
const UniqueVectorAllocator& vectorAllocator) VULKAN_HPP_NOEXCEPT {
std::vector<VULKAN_HPP_NAMESPACE::UniqueHandle<T, Dispatcher>, UniqueVectorAllocator> result(vectorAllocator);
result.reserve(vector.size());
for (const T& t : vector) result.emplace_back(t, o);
return result;
}
template<class T, class Owner> class Deleter {
const Owner* owner;
public:
Deleter() = default;
Deleter(const Owner* owner) VULKAN_HPP_NOEXCEPT : owner(owner) {}
protected:
void destroy(const T& t) VULKAN_HPP_NOEXCEPT; // Implemented manually for each handle type
};
template<class T> class Deleter<T, void> {
protected:
void destroy(const T& t) VULKAN_HPP_NOEXCEPT { t.destroy(); }
};
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct UniqueHandleTraits<Buffer, VMA_HPP_NAMESPACE::Dispatcher> {
using deleter = VMA_HPP_NAMESPACE::Deleter<Buffer, VMA_HPP_NAMESPACE::Allocator>;
};
template<> struct UniqueHandleTraits<Image, VMA_HPP_NAMESPACE::Dispatcher> {
using deleter = VMA_HPP_NAMESPACE::Deleter<Image, VMA_HPP_NAMESPACE::Allocator>;
};
}
namespace VMA_HPP_NAMESPACE {
using UniqueBuffer = VULKAN_HPP_NAMESPACE::UniqueHandle<VULKAN_HPP_NAMESPACE::Buffer, Dispatcher>;
using UniqueImage = VULKAN_HPP_NAMESPACE::UniqueHandle<VULKAN_HPP_NAMESPACE::Image, Dispatcher>;
}
#endif
#include "vk_mem_alloc_enums.hpp"
#include "vk_mem_alloc_handles.hpp"
#include "vk_mem_alloc_structs.hpp"
#include "vk_mem_alloc_funcs.hpp"
namespace VMA_HPP_NAMESPACE {
#ifndef VULKAN_HPP_NO_SMART_HANDLE
# define VMA_HPP_DESTROY_IMPL(NAME) \
template<> VULKAN_HPP_INLINE void VULKAN_HPP_NAMESPACE::UniqueHandleTraits<NAME, Dispatcher>::deleter::destroy(const NAME& t) VULKAN_HPP_NOEXCEPT
VMA_HPP_DESTROY_IMPL(VULKAN_HPP_NAMESPACE::Buffer) { owner->destroyBuffer(t, nullptr); }
VMA_HPP_DESTROY_IMPL(VULKAN_HPP_NAMESPACE::Image) { owner->destroyImage(t, nullptr); }
VMA_HPP_DESTROY_IMPL(Pool) { owner->destroyPool(t); }
VMA_HPP_DESTROY_IMPL(Allocation) { owner->freeMemory(t); }
VMA_HPP_DESTROY_IMPL(VirtualAllocation) { owner->virtualFree(t); }
# undef VMA_HPP_DESTROY_IMPL
#endif
template<class InstanceDispatcher, class DeviceDispatcher>
VULKAN_HPP_CONSTEXPR VulkanFunctions functionsFromDispatcher(InstanceDispatcher const * instance,
DeviceDispatcher const * device) VULKAN_HPP_NOEXCEPT {
return VulkanFunctions {
instance->vkGetInstanceProcAddr,
instance->vkGetDeviceProcAddr,
instance->vkGetPhysicalDeviceProperties,
instance->vkGetPhysicalDeviceMemoryProperties,
device->vkAllocateMemory,
device->vkFreeMemory,
device->vkMapMemory,
device->vkUnmapMemory,
device->vkFlushMappedMemoryRanges,
device->vkInvalidateMappedMemoryRanges,
device->vkBindBufferMemory,
device->vkBindImageMemory,
device->vkGetBufferMemoryRequirements,
device->vkGetImageMemoryRequirements,
device->vkCreateBuffer,
device->vkDestroyBuffer,
device->vkCreateImage,
device->vkDestroyImage,
device->vkCmdCopyBuffer,
device->vkGetBufferMemoryRequirements2KHR ? device->vkGetBufferMemoryRequirements2KHR : device->vkGetBufferMemoryRequirements2,
device->vkGetImageMemoryRequirements2KHR ? device->vkGetImageMemoryRequirements2KHR : device->vkGetImageMemoryRequirements2,
device->vkBindBufferMemory2KHR ? device->vkBindBufferMemory2KHR : device->vkBindBufferMemory2,
device->vkBindImageMemory2KHR ? device->vkBindImageMemory2KHR : device->vkBindImageMemory2,
instance->vkGetPhysicalDeviceMemoryProperties2KHR ? instance->vkGetPhysicalDeviceMemoryProperties2KHR : instance->vkGetPhysicalDeviceMemoryProperties2,
device->vkGetDeviceBufferMemoryRequirements,
device->vkGetDeviceImageMemoryRequirements
};
}
template<class Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>
VULKAN_HPP_CONSTEXPR VulkanFunctions functionsFromDispatcher(Dispatch const & dispatch
VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT) VULKAN_HPP_NOEXCEPT {
return functionsFromDispatcher(&dispatch, &dispatch);
}
}
#endif

View File

@@ -0,0 +1,478 @@
#ifndef VULKAN_MEMORY_ALLOCATOR_ENUMS_HPP
#define VULKAN_MEMORY_ALLOCATOR_ENUMS_HPP
namespace VMA_HPP_NAMESPACE {
enum class AllocatorCreateFlagBits : VmaAllocatorCreateFlags {
eExternallySynchronized = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT,
eKhrDedicatedAllocation = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT,
eKhrBindMemory2 = VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT,
eExtMemoryBudget = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT,
eAmdDeviceCoherentMemory = VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT,
eBufferDeviceAddress = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
eExtMemoryPriority = VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocatorCreateFlagBits value) {
if (value == AllocatorCreateFlagBits::eExternallySynchronized) return "ExternallySynchronized";
if (value == AllocatorCreateFlagBits::eKhrDedicatedAllocation) return "KhrDedicatedAllocation";
if (value == AllocatorCreateFlagBits::eKhrBindMemory2) return "KhrBindMemory2";
if (value == AllocatorCreateFlagBits::eExtMemoryBudget) return "ExtMemoryBudget";
if (value == AllocatorCreateFlagBits::eAmdDeviceCoherentMemory) return "AmdDeviceCoherentMemory";
if (value == AllocatorCreateFlagBits::eBufferDeviceAddress) return "BufferDeviceAddress";
if (value == AllocatorCreateFlagBits::eExtMemoryPriority) return "ExtMemoryPriority";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::AllocatorCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::AllocatorCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eExternallySynchronized
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eKhrDedicatedAllocation
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eKhrBindMemory2
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eExtMemoryBudget
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eAmdDeviceCoherentMemory
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eBufferDeviceAddress
| VMA_HPP_NAMESPACE::AllocatorCreateFlagBits::eExtMemoryPriority;
};
}
namespace VMA_HPP_NAMESPACE {
using AllocatorCreateFlags = VULKAN_HPP_NAMESPACE::Flags<AllocatorCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator|(AllocatorCreateFlagBits bit0, AllocatorCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocatorCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator&(AllocatorCreateFlagBits bit0, AllocatorCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocatorCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator^(AllocatorCreateFlagBits bit0, AllocatorCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocatorCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocatorCreateFlags operator~(AllocatorCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(AllocatorCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocatorCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & AllocatorCreateFlagBits::eExternallySynchronized) result += "ExternallySynchronized | ";
if (value & AllocatorCreateFlagBits::eKhrDedicatedAllocation) result += "KhrDedicatedAllocation | ";
if (value & AllocatorCreateFlagBits::eKhrBindMemory2) result += "KhrBindMemory2 | ";
if (value & AllocatorCreateFlagBits::eExtMemoryBudget) result += "ExtMemoryBudget | ";
if (value & AllocatorCreateFlagBits::eAmdDeviceCoherentMemory) result += "AmdDeviceCoherentMemory | ";
if (value & AllocatorCreateFlagBits::eBufferDeviceAddress) result += "BufferDeviceAddress | ";
if (value & AllocatorCreateFlagBits::eExtMemoryPriority) result += "ExtMemoryPriority | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class MemoryUsage {
eUnknown = VMA_MEMORY_USAGE_UNKNOWN,
eGpuOnly = VMA_MEMORY_USAGE_GPU_ONLY,
eCpuOnly = VMA_MEMORY_USAGE_CPU_ONLY,
eCpuToGpu = VMA_MEMORY_USAGE_CPU_TO_GPU,
eGpuToCpu = VMA_MEMORY_USAGE_GPU_TO_CPU,
eCpuCopy = VMA_MEMORY_USAGE_CPU_COPY,
eGpuLazilyAllocated = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED,
eAuto = VMA_MEMORY_USAGE_AUTO,
eAutoPreferDevice = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
eAutoPreferHost = VMA_MEMORY_USAGE_AUTO_PREFER_HOST
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(MemoryUsage value) {
if (value == MemoryUsage::eUnknown) return "Unknown";
if (value == MemoryUsage::eGpuOnly) return "GpuOnly";
if (value == MemoryUsage::eCpuOnly) return "CpuOnly";
if (value == MemoryUsage::eCpuToGpu) return "CpuToGpu";
if (value == MemoryUsage::eGpuToCpu) return "GpuToCpu";
if (value == MemoryUsage::eCpuCopy) return "CpuCopy";
if (value == MemoryUsage::eGpuLazilyAllocated) return "GpuLazilyAllocated";
if (value == MemoryUsage::eAuto) return "Auto";
if (value == MemoryUsage::eAutoPreferDevice) return "AutoPreferDevice";
if (value == MemoryUsage::eAutoPreferHost) return "AutoPreferHost";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class AllocationCreateFlagBits : VmaAllocationCreateFlags {
eDedicatedMemory = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
eNeverAllocate = VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT,
eMapped = VMA_ALLOCATION_CREATE_MAPPED_BIT,
eUserDataCopyString = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT,
eUpperAddress = VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,
eDontBind = VMA_ALLOCATION_CREATE_DONT_BIND_BIT,
eWithinBudget = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT,
eCanAlias = VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT,
eHostAccessSequentialWrite = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
eHostAccessRandom = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT,
eHostAccessAllowTransferInstead = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT,
eStrategyMinMemory = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
eStrategyMinTime = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
eStrategyMinOffset = VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT,
eStrategyBestFit = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT,
eStrategyFirstFit = VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocationCreateFlagBits value) {
if (value == AllocationCreateFlagBits::eDedicatedMemory) return "DedicatedMemory";
if (value == AllocationCreateFlagBits::eNeverAllocate) return "NeverAllocate";
if (value == AllocationCreateFlagBits::eMapped) return "Mapped";
if (value == AllocationCreateFlagBits::eUserDataCopyString) return "UserDataCopyString";
if (value == AllocationCreateFlagBits::eUpperAddress) return "UpperAddress";
if (value == AllocationCreateFlagBits::eDontBind) return "DontBind";
if (value == AllocationCreateFlagBits::eWithinBudget) return "WithinBudget";
if (value == AllocationCreateFlagBits::eCanAlias) return "CanAlias";
if (value == AllocationCreateFlagBits::eHostAccessSequentialWrite) return "HostAccessSequentialWrite";
if (value == AllocationCreateFlagBits::eHostAccessRandom) return "HostAccessRandom";
if (value == AllocationCreateFlagBits::eHostAccessAllowTransferInstead) return "HostAccessAllowTransferInstead";
if (value == AllocationCreateFlagBits::eStrategyMinMemory) return "StrategyMinMemory";
if (value == AllocationCreateFlagBits::eStrategyMinTime) return "StrategyMinTime";
if (value == AllocationCreateFlagBits::eStrategyMinOffset) return "StrategyMinOffset";
if (value == AllocationCreateFlagBits::eStrategyBestFit) return "StrategyBestFit";
if (value == AllocationCreateFlagBits::eStrategyFirstFit) return "StrategyFirstFit";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::AllocationCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::AllocationCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eDedicatedMemory
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eNeverAllocate
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eMapped
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eUserDataCopyString
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eUpperAddress
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eDontBind
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eWithinBudget
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eCanAlias
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eHostAccessSequentialWrite
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eHostAccessRandom
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eHostAccessAllowTransferInstead
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyMinMemory
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyMinTime
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyMinOffset
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyBestFit
| VMA_HPP_NAMESPACE::AllocationCreateFlagBits::eStrategyFirstFit;
};
}
namespace VMA_HPP_NAMESPACE {
using AllocationCreateFlags = VULKAN_HPP_NAMESPACE::Flags<AllocationCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator|(AllocationCreateFlagBits bit0, AllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocationCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator&(AllocationCreateFlagBits bit0, AllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocationCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator^(AllocationCreateFlagBits bit0, AllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return AllocationCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR AllocationCreateFlags operator~(AllocationCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(AllocationCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(AllocationCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & AllocationCreateFlagBits::eDedicatedMemory) result += "DedicatedMemory | ";
if (value & AllocationCreateFlagBits::eNeverAllocate) result += "NeverAllocate | ";
if (value & AllocationCreateFlagBits::eMapped) result += "Mapped | ";
if (value & AllocationCreateFlagBits::eUserDataCopyString) result += "UserDataCopyString | ";
if (value & AllocationCreateFlagBits::eUpperAddress) result += "UpperAddress | ";
if (value & AllocationCreateFlagBits::eDontBind) result += "DontBind | ";
if (value & AllocationCreateFlagBits::eWithinBudget) result += "WithinBudget | ";
if (value & AllocationCreateFlagBits::eCanAlias) result += "CanAlias | ";
if (value & AllocationCreateFlagBits::eHostAccessSequentialWrite) result += "HostAccessSequentialWrite | ";
if (value & AllocationCreateFlagBits::eHostAccessRandom) result += "HostAccessRandom | ";
if (value & AllocationCreateFlagBits::eHostAccessAllowTransferInstead) result += "HostAccessAllowTransferInstead | ";
if (value & AllocationCreateFlagBits::eStrategyMinMemory) result += "StrategyMinMemory | ";
if (value & AllocationCreateFlagBits::eStrategyMinTime) result += "StrategyMinTime | ";
if (value & AllocationCreateFlagBits::eStrategyMinOffset) result += "StrategyMinOffset | ";
if (value & AllocationCreateFlagBits::eStrategyBestFit) result += "StrategyBestFit | ";
if (value & AllocationCreateFlagBits::eStrategyFirstFit) result += "StrategyFirstFit | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class PoolCreateFlagBits : VmaPoolCreateFlags {
eIgnoreBufferImageGranularity = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT,
eLinearAlgorithm = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(PoolCreateFlagBits value) {
if (value == PoolCreateFlagBits::eIgnoreBufferImageGranularity) return "IgnoreBufferImageGranularity";
if (value == PoolCreateFlagBits::eLinearAlgorithm) return "LinearAlgorithm";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::PoolCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::PoolCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::PoolCreateFlagBits::eIgnoreBufferImageGranularity
| VMA_HPP_NAMESPACE::PoolCreateFlagBits::eLinearAlgorithm;
};
}
namespace VMA_HPP_NAMESPACE {
using PoolCreateFlags = VULKAN_HPP_NAMESPACE::Flags<PoolCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator|(PoolCreateFlagBits bit0, PoolCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return PoolCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator&(PoolCreateFlagBits bit0, PoolCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return PoolCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator^(PoolCreateFlagBits bit0, PoolCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return PoolCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR PoolCreateFlags operator~(PoolCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(PoolCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(PoolCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & PoolCreateFlagBits::eIgnoreBufferImageGranularity) result += "IgnoreBufferImageGranularity | ";
if (value & PoolCreateFlagBits::eLinearAlgorithm) result += "LinearAlgorithm | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class DefragmentationFlagBits : VmaDefragmentationFlags {
eFlagAlgorithmFast = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT,
eFlagAlgorithmBalanced = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT,
eFlagAlgorithmFull = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT,
eFlagAlgorithmExtensive = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(DefragmentationFlagBits value) {
if (value == DefragmentationFlagBits::eFlagAlgorithmFast) return "FlagAlgorithmFast";
if (value == DefragmentationFlagBits::eFlagAlgorithmBalanced) return "FlagAlgorithmBalanced";
if (value == DefragmentationFlagBits::eFlagAlgorithmFull) return "FlagAlgorithmFull";
if (value == DefragmentationFlagBits::eFlagAlgorithmExtensive) return "FlagAlgorithmExtensive";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::DefragmentationFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::DefragmentationFlagBits> allFlags =
VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmFast
| VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmBalanced
| VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmFull
| VMA_HPP_NAMESPACE::DefragmentationFlagBits::eFlagAlgorithmExtensive;
};
}
namespace VMA_HPP_NAMESPACE {
using DefragmentationFlags = VULKAN_HPP_NAMESPACE::Flags<DefragmentationFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator|(DefragmentationFlagBits bit0, DefragmentationFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return DefragmentationFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator&(DefragmentationFlagBits bit0, DefragmentationFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return DefragmentationFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator^(DefragmentationFlagBits bit0, DefragmentationFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return DefragmentationFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR DefragmentationFlags operator~(DefragmentationFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(DefragmentationFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(DefragmentationFlags value) {
if (!value) return "{}";
std::string result;
if (value & DefragmentationFlagBits::eFlagAlgorithmFast) result += "FlagAlgorithmFast | ";
if (value & DefragmentationFlagBits::eFlagAlgorithmBalanced) result += "FlagAlgorithmBalanced | ";
if (value & DefragmentationFlagBits::eFlagAlgorithmFull) result += "FlagAlgorithmFull | ";
if (value & DefragmentationFlagBits::eFlagAlgorithmExtensive) result += "FlagAlgorithmExtensive | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class DefragmentationMoveOperation {
eCopy = VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY,
eIgnore = VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE,
eDestroy = VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(DefragmentationMoveOperation value) {
if (value == DefragmentationMoveOperation::eCopy) return "Copy";
if (value == DefragmentationMoveOperation::eIgnore) return "Ignore";
if (value == DefragmentationMoveOperation::eDestroy) return "Destroy";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class VirtualBlockCreateFlagBits : VmaVirtualBlockCreateFlags {
eLinearAlgorithm = VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualBlockCreateFlagBits value) {
if (value == VirtualBlockCreateFlagBits::eLinearAlgorithm) return "LinearAlgorithm";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::VirtualBlockCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::VirtualBlockCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::VirtualBlockCreateFlagBits::eLinearAlgorithm;
};
}
namespace VMA_HPP_NAMESPACE {
using VirtualBlockCreateFlags = VULKAN_HPP_NAMESPACE::Flags<VirtualBlockCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator|(VirtualBlockCreateFlagBits bit0, VirtualBlockCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualBlockCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator&(VirtualBlockCreateFlagBits bit0, VirtualBlockCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualBlockCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator^(VirtualBlockCreateFlagBits bit0, VirtualBlockCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualBlockCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualBlockCreateFlags operator~(VirtualBlockCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(VirtualBlockCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualBlockCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & VirtualBlockCreateFlagBits::eLinearAlgorithm) result += "LinearAlgorithm | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
namespace VMA_HPP_NAMESPACE {
enum class VirtualAllocationCreateFlagBits : VmaVirtualAllocationCreateFlags {
eUpperAddress = VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,
eStrategyMinMemory = VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT,
eStrategyMinTime = VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT,
eStrategyMinOffset = VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT
};
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualAllocationCreateFlagBits value) {
if (value == VirtualAllocationCreateFlagBits::eUpperAddress) return "UpperAddress";
if (value == VirtualAllocationCreateFlagBits::eStrategyMinMemory) return "StrategyMinMemory";
if (value == VirtualAllocationCreateFlagBits::eStrategyMinTime) return "StrategyMinTime";
if (value == VirtualAllocationCreateFlagBits::eStrategyMinOffset) return "StrategyMinOffset";
return "invalid ( " + VULKAN_HPP_NAMESPACE::toHexString(static_cast<uint32_t>(value)) + " )";
}
# endif
}
namespace VULKAN_HPP_NAMESPACE {
template<> struct FlagTraits<VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits> {
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
static VULKAN_HPP_CONST_OR_CONSTEXPR Flags<VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits> allFlags =
VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eUpperAddress
| VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eStrategyMinMemory
| VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eStrategyMinTime
| VMA_HPP_NAMESPACE::VirtualAllocationCreateFlagBits::eStrategyMinOffset;
};
}
namespace VMA_HPP_NAMESPACE {
using VirtualAllocationCreateFlags = VULKAN_HPP_NAMESPACE::Flags<VirtualAllocationCreateFlagBits>;
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator|(VirtualAllocationCreateFlagBits bit0, VirtualAllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualAllocationCreateFlags(bit0) | bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator&(VirtualAllocationCreateFlagBits bit0, VirtualAllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualAllocationCreateFlags(bit0) & bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator^(VirtualAllocationCreateFlagBits bit0, VirtualAllocationCreateFlagBits bit1) VULKAN_HPP_NOEXCEPT {
return VirtualAllocationCreateFlags(bit0) ^ bit1;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR VirtualAllocationCreateFlags operator~(VirtualAllocationCreateFlagBits bits) VULKAN_HPP_NOEXCEPT {
return ~(VirtualAllocationCreateFlags(bits));
}
# if !defined( VULKAN_HPP_NO_TO_STRING )
VULKAN_HPP_INLINE std::string to_string(VirtualAllocationCreateFlags value) {
if (!value) return "{}";
std::string result;
if (value & VirtualAllocationCreateFlagBits::eUpperAddress) result += "UpperAddress | ";
if (value & VirtualAllocationCreateFlagBits::eStrategyMinMemory) result += "StrategyMinMemory | ";
if (value & VirtualAllocationCreateFlagBits::eStrategyMinTime) result += "StrategyMinTime | ";
if (value & VirtualAllocationCreateFlagBits::eStrategyMinOffset) result += "StrategyMinOffset | ";
return "{ " + result.substr( 0, result.size() - 3 ) + " }";
}
# endif
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,935 @@
#ifndef VULKAN_MEMORY_ALLOCATOR_HANDLES_HPP
#define VULKAN_MEMORY_ALLOCATOR_HANDLES_HPP
namespace VMA_HPP_NAMESPACE {
struct DeviceMemoryCallbacks;
struct VulkanFunctions;
struct AllocatorCreateInfo;
struct AllocatorInfo;
struct Statistics;
struct DetailedStatistics;
struct TotalStatistics;
struct Budget;
struct AllocationCreateInfo;
struct PoolCreateInfo;
struct AllocationInfo;
struct DefragmentationInfo;
struct DefragmentationMove;
struct DefragmentationPassMoveInfo;
struct DefragmentationStats;
struct VirtualBlockCreateInfo;
struct VirtualAllocationCreateInfo;
struct VirtualAllocationInfo;
class Allocator;
class Pool;
class Allocation;
class DefragmentationContext;
class VirtualAllocation;
class VirtualBlock;
}
namespace VMA_HPP_NAMESPACE {
class Pool {
public:
using CType = VmaPool;
using NativeType = VmaPool;
public:
VULKAN_HPP_CONSTEXPR Pool() = default;
VULKAN_HPP_CONSTEXPR Pool(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT Pool(VmaPool pool) VULKAN_HPP_NOEXCEPT : m_pool(pool) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
Pool& operator=(VmaPool pool) VULKAN_HPP_NOEXCEPT {
m_pool = pool;
return *this;
}
#endif
Pool& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_pool = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(Pool const &) const = default;
#else
bool operator==(Pool const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_pool == rhs.m_pool;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaPool() const VULKAN_HPP_NOEXCEPT {
return m_pool;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_pool != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_pool == VK_NULL_HANDLE;
}
private:
VmaPool m_pool = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(Pool) == sizeof(VmaPool),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::Pool, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::Pool, VMA_HPP_NAMESPACE::Allocator>;
};
}
namespace VMA_HPP_NAMESPACE { using UniquePool = VULKAN_HPP_NAMESPACE::UniqueHandle<Pool, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class Allocation {
public:
using CType = VmaAllocation;
using NativeType = VmaAllocation;
public:
VULKAN_HPP_CONSTEXPR Allocation() = default;
VULKAN_HPP_CONSTEXPR Allocation(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT Allocation(VmaAllocation allocation) VULKAN_HPP_NOEXCEPT : m_allocation(allocation) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
Allocation& operator=(VmaAllocation allocation) VULKAN_HPP_NOEXCEPT {
m_allocation = allocation;
return *this;
}
#endif
Allocation& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_allocation = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(Allocation const &) const = default;
#else
bool operator==(Allocation const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_allocation == rhs.m_allocation;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaAllocation() const VULKAN_HPP_NOEXCEPT {
return m_allocation;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_allocation != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_allocation == VK_NULL_HANDLE;
}
private:
VmaAllocation m_allocation = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(Allocation) == sizeof(VmaAllocation),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::Allocation, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::Allocation, VMA_HPP_NAMESPACE::Allocator>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueAllocation = VULKAN_HPP_NAMESPACE::UniqueHandle<Allocation, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class DefragmentationContext {
public:
using CType = VmaDefragmentationContext;
using NativeType = VmaDefragmentationContext;
public:
VULKAN_HPP_CONSTEXPR DefragmentationContext() = default;
VULKAN_HPP_CONSTEXPR DefragmentationContext(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT DefragmentationContext(VmaDefragmentationContext defragmentationContext) VULKAN_HPP_NOEXCEPT : m_defragmentationContext(defragmentationContext) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
DefragmentationContext& operator=(VmaDefragmentationContext defragmentationContext) VULKAN_HPP_NOEXCEPT {
m_defragmentationContext = defragmentationContext;
return *this;
}
#endif
DefragmentationContext& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_defragmentationContext = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(DefragmentationContext const &) const = default;
#else
bool operator==(DefragmentationContext const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext == rhs.m_defragmentationContext;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaDefragmentationContext() const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_defragmentationContext == VK_NULL_HANDLE;
}
private:
VmaDefragmentationContext m_defragmentationContext = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(DefragmentationContext) == sizeof(VmaDefragmentationContext),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::DefragmentationContext, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::DefragmentationContext, void>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueDefragmentationContext = VULKAN_HPP_NAMESPACE::UniqueHandle<DefragmentationContext, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class Allocator {
public:
using CType = VmaAllocator;
using NativeType = VmaAllocator;
public:
VULKAN_HPP_CONSTEXPR Allocator() = default;
VULKAN_HPP_CONSTEXPR Allocator(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT Allocator(VmaAllocator allocator) VULKAN_HPP_NOEXCEPT : m_allocator(allocator) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
Allocator& operator=(VmaAllocator allocator) VULKAN_HPP_NOEXCEPT {
m_allocator = allocator;
return *this;
}
#endif
Allocator& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_allocator = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(Allocator const &) const = default;
#else
bool operator==(Allocator const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_allocator == rhs.m_allocator;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaAllocator() const VULKAN_HPP_NOEXCEPT {
return m_allocator;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_allocator != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_allocator == VK_NULL_HANDLE;
}
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroy() const;
#else
void destroy() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS AllocatorInfo getAllocatorInfo() const;
#endif
void getAllocatorInfo(AllocatorInfo* allocatorInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS const VULKAN_HPP_NAMESPACE::PhysicalDeviceProperties* getPhysicalDeviceProperties() const;
#endif
void getPhysicalDeviceProperties(const VULKAN_HPP_NAMESPACE::PhysicalDeviceProperties** physicalDeviceProperties) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS const VULKAN_HPP_NAMESPACE::PhysicalDeviceMemoryProperties* getMemoryProperties() const;
#endif
void getMemoryProperties(const VULKAN_HPP_NAMESPACE::PhysicalDeviceMemoryProperties** physicalDeviceMemoryProperties) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VULKAN_HPP_NAMESPACE::MemoryPropertyFlags getMemoryTypeProperties(uint32_t memoryTypeIndex) const;
#endif
void getMemoryTypeProperties(uint32_t memoryTypeIndex,
VULKAN_HPP_NAMESPACE::MemoryPropertyFlags* flags) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setCurrentFrameIndex(uint32_t frameIndex) const;
#else
void setCurrentFrameIndex(uint32_t frameIndex) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS TotalStatistics calculateStatistics() const;
#endif
void calculateStatistics(TotalStatistics* stats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
template<typename VectorAllocator = std::allocator<Budget>,
typename B = VectorAllocator,
typename std::enable_if<std::is_same<typename B::value_type, Budget>::value, int>::type = 0>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS std::vector<Budget, VectorAllocator> getHeapBudgets(VectorAllocator& vectorAllocator) const;
template<typename VectorAllocator = std::allocator<Budget>>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS std::vector<Budget, VectorAllocator> getHeapBudgets() const;
#endif
void getHeapBudgets(Budget* budgets) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<uint32_t>::type findMemoryTypeIndex(uint32_t memoryTypeBits,
const AllocationCreateInfo& allocationCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result findMemoryTypeIndex(uint32_t memoryTypeBits,
const AllocationCreateInfo* allocationCreateInfo,
uint32_t* memoryTypeIndex) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<uint32_t>::type findMemoryTypeIndexForBufferInfo(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result findMemoryTypeIndexForBufferInfo(const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
uint32_t* memoryTypeIndex) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<uint32_t>::type findMemoryTypeIndexForImageInfo(const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo,
const AllocationCreateInfo& allocationCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result findMemoryTypeIndexForImageInfo(const VULKAN_HPP_NAMESPACE::ImageCreateInfo* imageCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
uint32_t* memoryTypeIndex) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Pool>::type createPool(const PoolCreateInfo& createInfo) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniquePool>::type createPoolUnique(const PoolCreateInfo& createInfo) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createPool(const PoolCreateInfo* createInfo,
Pool* pool) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroyPool(Pool pool) const;
#else
void destroyPool(Pool pool) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS Statistics getPoolStatistics(Pool pool) const;
#endif
void getPoolStatistics(Pool pool,
Statistics* poolStats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS DetailedStatistics calculatePoolStatistics(Pool pool) const;
#endif
void calculatePoolStatistics(Pool pool,
DetailedStatistics* poolStats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type checkPoolCorruption(Pool pool) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result checkPoolCorruption(Pool pool) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS const char* getPoolName(Pool pool) const;
#endif
void getPoolName(Pool pool,
const char** name) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setPoolName(Pool pool,
const char* name) const;
#else
void setPoolName(Pool pool,
const char* name) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocation>::type allocateMemory(const VULKAN_HPP_NAMESPACE::MemoryRequirements& vkMemoryRequirements,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocation>::type allocateMemoryUnique(const VULKAN_HPP_NAMESPACE::MemoryRequirements& vkMemoryRequirements,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemory(const VULKAN_HPP_NAMESPACE::MemoryRequirements* vkMemoryRequirements,
const AllocationCreateInfo* createInfo,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
template<typename VectorAllocator = std::allocator<Allocation>,
typename B = VectorAllocator,
typename std::enable_if<std::is_same<typename B::value_type, Allocation>::value, int>::type = 0>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<Allocation, VectorAllocator>>::type allocateMemoryPages(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo,
VectorAllocator& vectorAllocator) const;
template<typename VectorAllocator = std::allocator<Allocation>>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<Allocation, VectorAllocator>>::type allocateMemoryPages(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
template<typename VectorAllocator = std::allocator<UniqueAllocation>,
typename B = VectorAllocator,
typename std::enable_if<std::is_same<typename B::value_type, UniqueAllocation>::value, int>::type = 0>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<UniqueAllocation, VectorAllocator>>::type allocateMemoryPagesUnique(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo,
VectorAllocator& vectorAllocator) const;
template<typename VectorAllocator = std::allocator<UniqueAllocation>>
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::vector<UniqueAllocation, VectorAllocator>>::type allocateMemoryPagesUnique(VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::MemoryRequirements> vkMemoryRequirements,
VULKAN_HPP_NAMESPACE::ArrayProxy<const AllocationCreateInfo> createInfo,
VULKAN_HPP_NAMESPACE::ArrayProxyNoTemporaries<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemoryPages(const VULKAN_HPP_NAMESPACE::MemoryRequirements* vkMemoryRequirements,
const AllocationCreateInfo* createInfo,
size_t allocationCount,
Allocation* allocations,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocation>::type allocateMemoryForBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocation>::type allocateMemoryForBufferUnique(VULKAN_HPP_NAMESPACE::Buffer buffer,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemoryForBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
const AllocationCreateInfo* createInfo,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocation>::type allocateMemoryForImage(VULKAN_HPP_NAMESPACE::Image image,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocation>::type allocateMemoryForImageUnique(VULKAN_HPP_NAMESPACE::Image image,
const AllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result allocateMemoryForImage(VULKAN_HPP_NAMESPACE::Image image,
const AllocationCreateInfo* createInfo,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeMemory(Allocation allocation) const;
#else
void freeMemory(Allocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeMemoryPages(VULKAN_HPP_NAMESPACE::ArrayProxy<const Allocation> allocations) const;
#endif
void freeMemoryPages(size_t allocationCount,
const Allocation* allocations) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS AllocationInfo getAllocationInfo(Allocation allocation) const;
#endif
void getAllocationInfo(Allocation allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setAllocationUserData(Allocation allocation,
void* userData) const;
#else
void setAllocationUserData(Allocation allocation,
void* userData) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setAllocationName(Allocation allocation,
const char* name) const;
#else
void setAllocationName(Allocation allocation,
const char* name) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VULKAN_HPP_NAMESPACE::MemoryPropertyFlags getAllocationMemoryProperties(Allocation allocation) const;
#endif
void getAllocationMemoryProperties(Allocation allocation,
VULKAN_HPP_NAMESPACE::MemoryPropertyFlags* flags) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<void*>::type mapMemory(Allocation allocation) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result mapMemory(Allocation allocation,
void** data) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void unmapMemory(Allocation allocation) const;
#else
void unmapMemory(Allocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type flushAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result flushAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type invalidateAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result invalidateAllocation(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize offset,
VULKAN_HPP_NAMESPACE::DeviceSize size) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type flushAllocations(VULKAN_HPP_NAMESPACE::ArrayProxy<const Allocation> allocations,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> offsets,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> sizes) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result flushAllocations(uint32_t allocationCount,
const Allocation* allocations,
const VULKAN_HPP_NAMESPACE::DeviceSize* offsets,
const VULKAN_HPP_NAMESPACE::DeviceSize* sizes) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type invalidateAllocations(VULKAN_HPP_NAMESPACE::ArrayProxy<const Allocation> allocations,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> offsets,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::DeviceSize> sizes) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result invalidateAllocations(uint32_t allocationCount,
const Allocation* allocations,
const VULKAN_HPP_NAMESPACE::DeviceSize* offsets,
const VULKAN_HPP_NAMESPACE::DeviceSize* sizes) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type checkCorruption(uint32_t memoryTypeBits) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result checkCorruption(uint32_t memoryTypeBits) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<DefragmentationContext>::type beginDefragmentation(const DefragmentationInfo& info) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result beginDefragmentation(const DefragmentationInfo* info,
DefragmentationContext* context) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void endDefragmentation(DefragmentationContext context,
VULKAN_HPP_NAMESPACE::Optional<DefragmentationStats> stats = nullptr) const;
#endif
void endDefragmentation(DefragmentationContext context,
DefragmentationStats* stats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<DefragmentationPassMoveInfo>::type beginDefragmentationPass(DefragmentationContext context) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result beginDefragmentationPass(DefragmentationContext context,
DefragmentationPassMoveInfo* passInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<DefragmentationPassMoveInfo>::type endDefragmentationPass(DefragmentationContext context) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result endDefragmentationPass(DefragmentationContext context,
DefragmentationPassMoveInfo* passInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindBufferMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Buffer buffer) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindBufferMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Buffer buffer) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindBufferMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Buffer buffer,
const void* next) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindBufferMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Buffer buffer,
const void* next) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindImageMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Image image) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindImageMemory(Allocation allocation,
VULKAN_HPP_NAMESPACE::Image image) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
typename VULKAN_HPP_NAMESPACE::ResultValueType<void>::type bindImageMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Image image,
const void* next) const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result bindImageMemory2(Allocation allocation,
VULKAN_HPP_NAMESPACE::DeviceSize allocationLocalOffset,
VULKAN_HPP_NAMESPACE::Image image,
const void* next) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<VULKAN_HPP_NAMESPACE::Buffer, Allocation>>::type createBuffer(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<UniqueBuffer, UniqueAllocation>>::type createBufferUnique(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createBuffer(const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Buffer* buffer,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<VULKAN_HPP_NAMESPACE::Buffer, Allocation>>::type createBufferWithAlignment(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::DeviceSize minAlignment,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<UniqueBuffer, UniqueAllocation>>::type createBufferWithAlignmentUnique(const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::DeviceSize minAlignment,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createBufferWithAlignment(const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
VULKAN_HPP_NAMESPACE::DeviceSize minAlignment,
VULKAN_HPP_NAMESPACE::Buffer* buffer,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VULKAN_HPP_NAMESPACE::Buffer>::type createAliasingBuffer(Allocation allocation,
const VULKAN_HPP_NAMESPACE::BufferCreateInfo& bufferCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createAliasingBuffer(Allocation allocation,
const VULKAN_HPP_NAMESPACE::BufferCreateInfo* bufferCreateInfo,
VULKAN_HPP_NAMESPACE::Buffer* buffer) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroyBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
Allocation allocation) const;
#else
void destroyBuffer(VULKAN_HPP_NAMESPACE::Buffer buffer,
Allocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<VULKAN_HPP_NAMESPACE::Image, Allocation>>::type createImage(const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<std::pair<UniqueImage, UniqueAllocation>>::type createImageUnique(const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo,
const AllocationCreateInfo& allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Optional<AllocationInfo> allocationInfo = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createImage(const VULKAN_HPP_NAMESPACE::ImageCreateInfo* imageCreateInfo,
const AllocationCreateInfo* allocationCreateInfo,
VULKAN_HPP_NAMESPACE::Image* image,
Allocation* allocation,
AllocationInfo* allocationInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VULKAN_HPP_NAMESPACE::Image>::type createAliasingImage(Allocation allocation,
const VULKAN_HPP_NAMESPACE::ImageCreateInfo& imageCreateInfo) const;
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createAliasingImage(Allocation allocation,
const VULKAN_HPP_NAMESPACE::ImageCreateInfo* imageCreateInfo,
VULKAN_HPP_NAMESPACE::Image* image) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroyImage(VULKAN_HPP_NAMESPACE::Image image,
Allocation allocation) const;
#else
void destroyImage(VULKAN_HPP_NAMESPACE::Image image,
Allocation allocation) const;
#endif
#if VMA_STATS_STRING_ENABLED
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS char* buildStatsString(VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#endif
void buildStatsString(char** statsString,
VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeStatsString(char* statsString) const;
#else
void freeStatsString(char* statsString) const;
#endif
#endif
private:
VmaAllocator m_allocator = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(Allocator) == sizeof(VmaAllocator),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::Allocator, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::Allocator, void>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueAllocator = VULKAN_HPP_NAMESPACE::UniqueHandle<Allocator, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class VirtualAllocation {
public:
using CType = VmaVirtualAllocation;
using NativeType = VmaVirtualAllocation;
public:
VULKAN_HPP_CONSTEXPR VirtualAllocation() = default;
VULKAN_HPP_CONSTEXPR VirtualAllocation(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT VirtualAllocation(VmaVirtualAllocation virtualAllocation) VULKAN_HPP_NOEXCEPT : m_virtualAllocation(virtualAllocation) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
VirtualAllocation& operator=(VmaVirtualAllocation virtualAllocation) VULKAN_HPP_NOEXCEPT {
m_virtualAllocation = virtualAllocation;
return *this;
}
#endif
VirtualAllocation& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_virtualAllocation = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(VirtualAllocation const &) const = default;
#else
bool operator==(VirtualAllocation const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation == rhs.m_virtualAllocation;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaVirtualAllocation() const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_virtualAllocation == VK_NULL_HANDLE;
}
private:
VmaVirtualAllocation m_virtualAllocation = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(VirtualAllocation) == sizeof(VmaVirtualAllocation),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::VirtualAllocation, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::VirtualAllocation, VMA_HPP_NAMESPACE::VirtualBlock>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueVirtualAllocation = VULKAN_HPP_NAMESPACE::UniqueHandle<VirtualAllocation, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
class VirtualBlock {
public:
using CType = VmaVirtualBlock;
using NativeType = VmaVirtualBlock;
public:
VULKAN_HPP_CONSTEXPR VirtualBlock() = default;
VULKAN_HPP_CONSTEXPR VirtualBlock(std::nullptr_t) VULKAN_HPP_NOEXCEPT {}
VULKAN_HPP_TYPESAFE_EXPLICIT VirtualBlock(VmaVirtualBlock virtualBlock) VULKAN_HPP_NOEXCEPT : m_virtualBlock(virtualBlock) {}
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
VirtualBlock& operator=(VmaVirtualBlock virtualBlock) VULKAN_HPP_NOEXCEPT {
m_virtualBlock = virtualBlock;
return *this;
}
#endif
VirtualBlock& operator=(std::nullptr_t) VULKAN_HPP_NOEXCEPT {
m_virtualBlock = {};
return *this;
}
#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
auto operator<=>(VirtualBlock const &) const = default;
#else
bool operator==(VirtualBlock const & rhs) const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock == rhs.m_virtualBlock;
}
#endif
VULKAN_HPP_TYPESAFE_EXPLICIT operator VmaVirtualBlock() const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock;
}
explicit operator bool() const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock != VK_NULL_HANDLE;
}
bool operator!() const VULKAN_HPP_NOEXCEPT {
return m_virtualBlock == VK_NULL_HANDLE;
}
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void destroy() const;
#else
void destroy() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VULKAN_HPP_NAMESPACE::Bool32 isVirtualBlockEmpty() const;
#else
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Bool32 isVirtualBlockEmpty() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS VirtualAllocationInfo getVirtualAllocationInfo(VirtualAllocation allocation) const;
#endif
void getVirtualAllocationInfo(VirtualAllocation allocation,
VirtualAllocationInfo* virtualAllocInfo) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VirtualAllocation>::type virtualAllocate(const VirtualAllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<VULKAN_HPP_NAMESPACE::DeviceSize> offset = nullptr) const;
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueVirtualAllocation>::type virtualAllocateUnique(const VirtualAllocationCreateInfo& createInfo,
VULKAN_HPP_NAMESPACE::Optional<VULKAN_HPP_NAMESPACE::DeviceSize> offset = nullptr) const;
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result virtualAllocate(const VirtualAllocationCreateInfo* createInfo,
VirtualAllocation* allocation,
VULKAN_HPP_NAMESPACE::DeviceSize* offset) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void virtualFree(VirtualAllocation allocation) const;
#else
void virtualFree(VirtualAllocation allocation) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void clearVirtualBlock() const;
#else
void clearVirtualBlock() const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void setVirtualAllocationUserData(VirtualAllocation allocation,
void* userData) const;
#else
void setVirtualAllocationUserData(VirtualAllocation allocation,
void* userData) const;
#endif
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS Statistics getVirtualBlockStatistics() const;
#endif
void getVirtualBlockStatistics(Statistics* stats) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS DetailedStatistics calculateVirtualBlockStatistics() const;
#endif
void calculateVirtualBlockStatistics(DetailedStatistics* stats) const;
#if VMA_STATS_STRING_ENABLED
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS char* buildVirtualBlockStatsString(VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#endif
void buildVirtualBlockStatsString(char** statsString,
VULKAN_HPP_NAMESPACE::Bool32 detailedMap) const;
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
void freeVirtualBlockStatsString(char* statsString) const;
#else
void freeVirtualBlockStatsString(char* statsString) const;
#endif
#endif
private:
VmaVirtualBlock m_virtualBlock = {};
};
VULKAN_HPP_STATIC_ASSERT(sizeof(VirtualBlock) == sizeof(VmaVirtualBlock),
"handle and wrapper have different size!");
}
#ifndef VULKAN_HPP_NO_SMART_HANDLE
namespace VULKAN_HPP_NAMESPACE {
template<> class UniqueHandleTraits<VMA_HPP_NAMESPACE::VirtualBlock, VMA_HPP_NAMESPACE::Dispatcher> {
public:
using deleter = VMA_HPP_NAMESPACE::Deleter<VMA_HPP_NAMESPACE::VirtualBlock, void>;
};
}
namespace VMA_HPP_NAMESPACE { using UniqueVirtualBlock = VULKAN_HPP_NAMESPACE::UniqueHandle<VirtualBlock, Dispatcher>; }
#endif
namespace VMA_HPP_NAMESPACE {
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<Allocator>::type createAllocator(const AllocatorCreateInfo& createInfo);
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueAllocator>::type createAllocatorUnique(const AllocatorCreateInfo& createInfo);
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createAllocator(const AllocatorCreateInfo* createInfo,
Allocator* allocator);
#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<VirtualBlock>::type createVirtualBlock(const VirtualBlockCreateInfo& createInfo);
#ifndef VULKAN_HPP_NO_SMART_HANDLE
VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS typename VULKAN_HPP_NAMESPACE::ResultValueType<UniqueVirtualBlock>::type createVirtualBlockUnique(const VirtualBlockCreateInfo& createInfo);
#endif
#endif
VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::Result createVirtualBlock(const VirtualBlockCreateInfo* createInfo,
VirtualBlock* virtualBlock);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -104,6 +104,9 @@ abstract class XDecoratedPeer extends XWindowPeer {
void postInit(XCreateWindowParams params) {
// The size hints must be set BEFORE mapping the window (see 6895647)
updateSizeHints(dimensions);
if (isTargetUndecorated()) {
XWM.setGtkFrameExtents(window);
}
// The super method maps the window if it's visible on the shared level
super.postInit(params);

View File

@@ -93,6 +93,9 @@ final class XWM
/* Root window */
static final XAtom XA_NET_DESKTOP_GEOMETRY = new XAtom();
/* Mutter */
static final XAtom XA_GTK_FRAME_EXTENTS = new XAtom();
static final int
UNDETERMINED_WM = 1,
NO_WM = 2,
@@ -221,7 +224,8 @@ final class XWM
{ XA_MWM_HINTS, "_MOTIF_WM_HINTS" },
{ XA_NET_FRAME_EXTENTS, "_NET_FRAME_EXTENTS" },
{ XA_NET_REQUEST_FRAME_EXTENTS, "_NET_REQUEST_FRAME_EXTENTS" },
{ XA_NET_DESKTOP_GEOMETRY, "_NET_DESKTOP_GEOMETRY" }
{ XA_NET_DESKTOP_GEOMETRY, "_NET_DESKTOP_GEOMETRY" },
{ XA_GTK_FRAME_EXTENTS, "_GTK_FRAME_EXTENTS" }
};
String[] names = new String[atomInitList.length];
@@ -1830,6 +1834,30 @@ final class XWM
return false;
}
public static void setGtkFrameExtents(long window) {
// This will make Mutter think that we are "client-decorated"
// (see meta_window_is_client_decorated() in src/core/window.c of Mutter).
// It is necessary for some heuristics that Mutter has not to be applied.
long data = Native.allocateLongArray(4);
try {
Native.putLong(data, 0, 0);
Native.putLong(data, 1, 0);
Native.putLong(data, 2, 0);
Native.putLong(data, 3, 0);
XErrorHandlerUtil.WITH_XERROR_HANDLER(XErrorHandler.VerifyChangePropertyHandler.getInstance());
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), window,
XA_GTK_FRAME_EXTENTS.getAtom(),
XAtom.XA_CARDINAL,
32, XConstants.PropModeReplace,
data, 4);
XErrorHandlerUtil.RESTORE_XERROR_HANDLER();
} finally {
unsafe.freeMemory(data);
data = 0;
}
}
public static boolean isWMMoveResizeSupported() {
if (g_net_protocol == null) {
return false;

View File

@@ -0,0 +1,418 @@
/*
* Copyright 2023 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.wl;
import jdk.internal.misc.InnocuousThread;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.SunClipboard;
import sun.util.logging.PlatformLogger;
import javax.swing.SwingUtilities;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorTable;
import java.awt.datatransfer.Transferable;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.SortedMap;
public final class WLClipboard extends SunClipboard {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.WLClipboard");
public static final int INITIAL_MIME_FORMATS_COUNT = 10;
private static final int DEFAULT_BUFFER_SIZE = 4096;
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
// A native handle of a Wayland queue dedicated to handling
// data offer-related events
private static final long dataOfferQueuePtr;
private final long ID;
// true if this is the "primary selection" clipboard,
// false otherwise (the regular clipboard).
private final boolean isPrimary; // used by native
// A handle to the native clipboard representation, 0 if not available.
private long clipboardNativePtr; // guarded by 'this'
// The list of numeric format IDs the current clipboard is available in;
// could be null or empty.
private List<Long> clipboardFormats; // guarded by 'this'
// The "current" list formats for the new clipboard contents that is about
// to be received from Wayland. Could be empty, but never null.
private List<Long> newClipboardFormats = new ArrayList<>(INITIAL_MIME_FORMATS_COUNT); // guarded by 'this'
static {
initIDs();
dataOfferQueuePtr = createDataOfferQueue();
flavorTable = DataTransferer.adaptFlavorMap(getDefaultFlavorTable());
final Thread toolkitSystemThread = InnocuousThread.newThread(
"AWT-Wayland-clipboard-dispatcher",
WLClipboard::dispatchDataOfferQueue);
toolkitSystemThread.setDaemon(true);
toolkitSystemThread.start();
}
private final static FlavorTable flavorTable;
public WLClipboard(String name, boolean isPrimary) {
super(name);
this.ID = initNative(isPrimary);
this.isPrimary = isPrimary;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: Created " + this);
}
}
private static void dispatchDataOfferQueue() {
dispatchDataOfferQueueImpl(dataOfferQueuePtr); // does not return until error or server disconnect
if (log.isLoggable(PlatformLogger.Level.INFO)) {
log.info("Clipboard: data offer dispatcher exited");
}
}
@Override
public String toString() {
return String.format("Clipboard: Wayland %s (%x)", (isPrimary ? "selection clipboard" : "clipboard"), ID);
}
@Override
public long getID() {
return ID;
}
/**
* Called when we loose ownership of the clipboard.
*/
@Override
protected void clearNativeContext() {
// Unused in the Wayland clipboard as we don't (and can't) keep
// any references to the native clipboard once we have lost keyboard focus.
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: Lost ownership of our clipboard");
}
}
/**
* Called to make the new clipboard contents known to Wayland.
*
* @param contents clipboard's contents.
*/
@Override
protected void setContentsNative(Transferable contents) {
// The server requires "serial number of the event that triggered this request"
// as a proof of the right to copy data.
WLPointerEvent wlPointerEvent = WLToolkit.getInputState().eventWithSerial();
long eventSerial = wlPointerEvent == null ? 0 : wlPointerEvent.getSerial();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: About to offer new contents using Wayland event serial " + eventSerial);
}
if (eventSerial != 0) {
WLDataTransferer wlDataTransferer = (WLDataTransferer) DataTransferer.getInstance();
long[] formats = wlDataTransferer.getFormatsForTransferableAsArray(contents, flavorTable);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: New one is available in these integer formats: " + Arrays.toString(formats));
}
notifyOfNewFormats(formats);
if (formats.length > 0) {
String[] mime = new String[formats.length];
for (int i = 0; i < formats.length; i++) {
mime[i] = wlDataTransferer.getNativeForFormat(formats[i]);
}
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: Offering new contents (" + contents + ") in these MIME formats: " + Arrays.toString(mime));
}
offerData(eventSerial, mime, contents, dataOfferQueuePtr);
// Once we have offered the data, someone may come back and ask to provide them.
// In that event, the transferContentsWithType() will be called from native on EDT.
// A reference to contents is retained until we are notified of the new contents
// by the Wayland server.
}
} else {
this.owner = null;
this.contents = null;
}
}
/**
* Called from native on EDT when a client has asked to provide the actual data for
* the clipboard that we own in the given format to the given file.
* NB: that client could be us, but we aren't necessarily aware of that once we
* lost keyboard focus at least once after Ctrl-C.
*
* @param contents a reference to the clipboard's contents to be transferred
* @param mime transfer the contents in this MIME format
* @param destFD transfer the contents to this file descriptor and close it afterward
*
* @throws IOException in case writing to the given file descriptor failed
*/
private void transferContentsWithType(Transferable contents, String mime, int destFD) throws IOException {
assert SwingUtilities.isEventDispatchThread();
Objects.requireNonNull(contents);
Objects.requireNonNull(mime);
WLDataTransferer wlDataTransferer = (WLDataTransferer) DataTransferer.getInstance();
SortedMap<Long,DataFlavor> formatMap =
wlDataTransferer.getFormatsForTransferable(contents, flavorTable);
long targetFormat = wlDataTransferer.getFormatForNativeAsLong(mime);
DataFlavor flavor = formatMap.get(targetFormat);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: will write contents (" + contents + ") in format " + mime + " to fd=" + destFD);
log.fine("Clipboard: data flavor: " + flavor);
}
if (flavor != null) {
FileDescriptor javaDestFD = new FileDescriptor();
jdk.internal.access.SharedSecrets.getJavaIOFileDescriptorAccess().set(javaDestFD, destFD);
try (var out = new FileOutputStream(javaDestFD)) {
byte[] bytes = wlDataTransferer.translateTransferable(contents, flavor, targetFormat);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: about to write " + (bytes != null ? bytes.length : 0) + " bytes to " + out);
}
// TODO: large data transfer will block EDT for a long time.
// Implement an option to do the writing on a dedicated thread.
// Alternatively, arrange for this event to arrive on a dedicated queue and
// only work with this queue on a dedicated thread.
out.write(bytes);
}
}
}
/**
* @return formats the current clipboard is available in; could be null
*/
@Override
protected long[] getClipboardFormats() {
synchronized (this) {
if (clipboardFormats != null && !clipboardFormats.isEmpty()) {
long[] res = new long[clipboardFormats.size()];
for (int i = 0; i < res.length; i++) {
res[i] = clipboardFormats.get(i);
}
return res;
} else {
return null;
}
}
}
/**
* The clipboard contents in the given numeric format ID.
*
* @param format the numeric ID of the format to provide clipboard contents in
* @return contents in the given numeric format ID
* @throws IOException when reading from the clipboard file fails
*/
@Override
protected byte[] getClipboardData(long format) throws IOException {
synchronized (this) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: requested content of clipboard with handle "
+ clipboardNativePtr + " in format " + format);
}
if (clipboardNativePtr != 0) {
WLDataTransferer wlDataTransferer = (WLDataTransferer) DataTransferer.getInstance();
String mime = wlDataTransferer.getNativeForFormat(format);
int fd = requestDataInFormat(clipboardNativePtr, mime);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: will read data from " + fd + " in format " + mime);
}
if (fd >= 0) {
FileDescriptor javaFD = new FileDescriptor();
jdk.internal.access.SharedSecrets.getJavaIOFileDescriptorAccess().set(javaFD, fd);
try (var in = new FileInputStream(javaFD)) {
byte[] bytes = readAllBytesFrom(in);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: read data from " + fd + ": "
+ (bytes != null ? bytes.length : 0) + " bytes");
}
return bytes;
}
}
}
}
return null;
}
/**
* Called from native to notify us of the availability of a new clipboard
* denoted by the native handle in a specific MIME format.
* This method is usually called repeatedly with the same nativePtr and
* different formats. When all formats are announces in this way,
* handleNewClipboard() is called.
*
* @param nativePtr a native handle to the clipboard
* @param mime the MIME format in which this clipboard is available.
*/
private void handleClipboardFormat(long nativePtr, String mime) {
WLDataTransferer wlDataTransferer = (WLDataTransferer) DataTransferer.getInstance();
Long format = wlDataTransferer.getFormatForNativeAsLong(mime);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: new format is available for " + nativePtr + ": " + mime);
}
synchronized (this) {
newClipboardFormats.add(format);
}
}
/**
* Called from native to notify us that a new clipboard content
* has been made available. The list of supported formats
* should have already been received and saved in newClipboardFormats.
*
* @param nativePtr a native handle to the clipboard
*/
private void handleNewClipboard(long nativePtr) {
// Since we have a new clipboard, the existing one is no longer valid.
// We have now way of knowing whether this "new" one is the same as the "old" one.
lostOwnershipNow(null);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Clipboard: new clipboard is available: " + nativePtr);
}
synchronized (this) {
long oldClipboardNativePtr = clipboardNativePtr;
if (oldClipboardNativePtr != 0) {
destroyClipboard(oldClipboardNativePtr);
}
clipboardFormats = newClipboardFormats;
clipboardNativePtr = nativePtr; // Could be NULL
newClipboardFormats = new ArrayList<>(INITIAL_MIME_FORMATS_COUNT);
notifyOfNewFormats(getClipboardFormats());
}
}
@Override
protected void registerClipboardViewerChecked() {
// TODO: is there any need to do more here?
log.info("Unimplemented");
}
@Override
protected void unregisterClipboardViewerChecked() {
log.info("Unimplemented");
}
private void notifyOfNewFormats(long[] formats) {
if (areFlavorListenersRegistered()) {
checkChange(formats);
}
}
/**
* Reads the given input stream until EOF and returns its contents as an array of bytes.
*/
private byte[] readAllBytesFrom(FileInputStream inputStream) throws IOException {
int len = Integer.MAX_VALUE;
List<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int remaining = len;
int n;
do {
byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
int nread = 0;
while ((n = inputStream.read(buf, nread,
Math.min(buf.length - nread, remaining))) > 0) {
nread += n;
remaining -= n;
}
if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
if (nread < buf.length) {
buf = Arrays.copyOfRange(buf, 0, nread);
}
total += nread;
if (result == null) {
result = buf;
} else {
if (bufs == null) {
bufs = new ArrayList<>();
bufs.add(result);
}
bufs.add(buf);
}
}
// if the last call to read returned -1 or the number of bytes
// requested have been read then break
} while (n >= 0 && remaining > 0);
if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ?
result : Arrays.copyOf(result, total);
}
result = new byte[total];
int offset = 0;
remaining = total;
for (byte[] b : bufs) {
int count = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, count);
offset += count;
remaining -= count;
}
return result;
}
private static native void initIDs();
private static native long createDataOfferQueue();
private static native void dispatchDataOfferQueueImpl(long dataOfferQueuePtr);
private native long initNative(boolean isPrimary);
private native void offerData(long eventSerial, String[] mime, Object data, long dataOfferQueuePtr);
private native void cancelOffer(long eventSerial); // TODO: this is unused, delete, maybe?
private native int requestDataInFormat(long clipboardNativePtr, String mime);
private native void destroyClipboard(long clipboardNativePtr);
}

View File

@@ -147,15 +147,12 @@ public class WLComponentPeer implements ComponentPeer {
}
public void postPaintEvent(int x, int y, int w, int h) {
if (!hasSurface()) {
log.warning("WLComponentPeer: No surface. Skipping paint request x=" + x + " y=" + y +
" width=" + w + " height=" + h);
return;
}
PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher().
createPaintEvent(target, x, y, w, h);
if (event != null) {
WLToolkit.postEvent(event);
if (isVisible()) {
PaintEvent event = PaintEventDispatcher.getPaintEventDispatcher().
createPaintEvent(target, x, y, w, h);
if (event != null) {
WLToolkit.postEvent(event);
}
}
}
@@ -168,7 +165,7 @@ public class WLComponentPeer implements ComponentPeer {
}
boolean isVisible() {
return visible;
return visible && hasSurface();
}
boolean hasSurface() {
@@ -209,20 +206,17 @@ public class WLComponentPeer implements ComponentPeer {
public boolean requestFocus(Component lightweightChild, boolean temporary,
boolean focusedWindowChangeAllowed, long time,
FocusEvent.Cause cause) {
final Component currentlyFocused = WLKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
if (currentlyFocused == null)
final Window currentlyFocusedWindow = WLKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
if (currentlyFocusedWindow == null)
return false;
WLComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(currentlyFocused);
if (peer == null)
return false;
if (this == peer) {
Window targetDecoratedWindow = getNativelyFocusableOwnerOrSelf(target);
if (currentlyFocusedWindow == targetDecoratedWindow) {
WLKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
target,
null,
true,
cause,
WLKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner());
null);
} else {
return false;
}
@@ -232,13 +226,14 @@ public class WLComponentPeer implements ComponentPeer {
protected void wlSetVisible(boolean v) {
this.visible = v;
if (this.visible) {
if (v) {
final String title = getTitle();
final boolean isPopup = target instanceof Window window && window.getType() == Window.Type.POPUP;
final boolean isWlPopup = targetIsWlPopup();
final int thisWidth = getWidth();
final int thisHeight = getHeight();
final boolean isModal = targetIsModal();
performLocked(() -> {
if (isPopup) {
if (isWlPopup) {
Window popup = (Window) target;
final Component popupParent = AWTAccessor.getWindowAccessor().getPopupParent(popup);
final int parentWidth = popupParent.getWidth();
@@ -262,7 +257,10 @@ public class WLComponentPeer implements ComponentPeer {
offsetX, offsetY);
} else {
nativeCreateWLSurface(nativePtr,
getParentNativePtr(target), target.getX(), target.getY(), title, appID);
getParentNativePtr(target),
target.getX(), target.getY(),
isModal,
title, appID);
}
final long wlSurfacePtr = getWLSurface(nativePtr);
WLToolkit.registerWLSurface(wlSurfacePtr, this);
@@ -281,6 +279,25 @@ public class WLComponentPeer implements ComponentPeer {
}
}
/**
* Returns true if our target should be treated as a popup in Wayland's sense,
* i.e. it has to have a parent to position relative to.
*/
protected boolean targetIsWlPopup() {
return target instanceof Window window && isWlPopup(window);
}
static boolean isWlPopup(Window window) {
return window.getType() == Window.Type.POPUP
&& AWTAccessor.getWindowAccessor().getPopupParent(window) != null;
}
private boolean targetIsModal() {
return target instanceof Dialog dialog
&& (dialog.getModalityType() == Dialog.ModalityType.APPLICATION_MODAL
|| dialog.getModalityType() == Dialog.ModalityType.TOOLKIT_MODAL);
}
void configureWLSurface() {
synchronized (sizeLock) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
@@ -363,7 +380,7 @@ public class WLComponentPeer implements ComponentPeer {
public void setBounds(int x, int y, int width, int height, int op) {
final boolean positionChanged = this.x != x || this.y != y;
if (positionChanged) {
if (positionChanged && isVisible()) {
performLocked(() -> WLRobotPeer.setLocationOfWLSurface(getWLSurface(nativePtr), x, y));
}
this.x = x;
@@ -373,23 +390,25 @@ public class WLComponentPeer implements ComponentPeer {
WLToolkit.postEvent(new ComponentEvent(getTarget(), ComponentEvent.COMPONENT_MOVED));
}
synchronized(sizeLock) {
final boolean sizeChanged = this.width != width || this.height != height;
if (sizeChanged) {
Rectangle oldBounds = getVisibleBounds();
final boolean sizeChanged = oldBounds.width != width || oldBounds.height != height;
if (sizeChanged) {
synchronized (sizeLock) {
this.width = width;
this.height = height;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(String.format("%s is resizing its buffer to %dx%d with %dx scale", this, getBufferWidth(), getBufferHeight(), getBufferScale()));
}
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).revalidate(
getBufferWidth(), getBufferHeight(), getBufferScale());
updateWindowGeometry();
layout();
WLToolkit.postEvent(new ComponentEvent(getTarget(), ComponentEvent.COMPONENT_RESIZED));
}
postPaintEvent();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(String.format("%s is resizing its buffer to %dx%d with %dx scale", this, getBufferWidth(), getBufferHeight(), getBufferScale()));
}
SurfaceData.convertTo(WLSurfaceDataExt.class, surfaceData).revalidate(
getBufferWidth(), getBufferHeight(), getBufferScale());
updateWindowGeometry();
layout();
WLToolkit.postEvent(new ComponentEvent(getTarget(), ComponentEvent.COMPONENT_RESIZED));
}
postPaintEvent();
}
public Rectangle getVisibleBounds() {
@@ -642,6 +661,12 @@ public class WLComponentPeer implements ComponentPeer {
@Override
public void dispose() {
SurfaceData oldData = surfaceData;
surfaceData = null;
if (oldData != null) {
oldData.invalidate();
}
WLToolkit.targetDisposedPeer(target, this);
performLocked(() -> {
assert(!isVisible());
nativeDisposeFrame(nativePtr);
@@ -819,12 +844,16 @@ public class WLComponentPeer implements ComponentPeer {
performLocked(() -> nativeRequestUnsetFullScreen(nativePtr));
}
final void activate() {
performLocked(() -> nativeActivate(nativePtr));
}
private static native void initIDs();
protected native long nativeCreateFrame();
protected native void nativeCreateWLSurface(long ptr, long parentPtr,
int x, int y,
int x, int y, boolean isModal,
String title, String appID);
protected native void nativeCreateWLPopup(long ptr, long parentPtr,
@@ -853,6 +882,7 @@ public class WLComponentPeer implements ComponentPeer {
private static native void nativeSetCursor(long pData);
private static native long nativeGetPredefinedCursor(String name);
private native void nativeShowWindowMenu(long ptr, int x, int y);
private native void nativeActivate(long ptr);
static long getParentNativePtr(Component target) {
Component parent = target.getParent();
@@ -1002,11 +1032,11 @@ public class WLComponentPeer implements ComponentPeer {
log.fine(String.format("%s configured to %dx%d", this, newWidth, newHeight));
}
final boolean isPopup = target instanceof Window window && window.getType() == Window.Type.POPUP;
boolean isWlPopup = targetIsWlPopup();
if (newWidth != 0 && newHeight != 0) performUnlocked(() ->target.setSize(newWidth, newHeight));
if (newWidth == 0 || newHeight == 0 || isPopup) {
if (newWidth == 0 || newHeight == 0 || isWlPopup) {
// From xdg-shell.xml: "If the width or height arguments are zero,
// it means the client should decide its own window dimension".
@@ -1154,4 +1184,12 @@ public class WLComponentPeer implements ComponentPeer {
throw new IllegalArgumentException("AWT window must have WLComponentPeer as its peer");
}
}
static Window getNativelyFocusableOwnerOrSelf(Component component) {
Window result = component instanceof Window window ? window : SwingUtilities.getWindowAncestor(component);
while (result != null && isWlPopup(result)) {
result = result.getOwner();
}
return result;
}
}

View File

@@ -0,0 +1,357 @@
/*
* Copyright 2023 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.wl;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
import sun.datatransfer.DataFlavorUtil;
import sun.util.logging.PlatformLogger;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Objects;
/**
* Facilitates data conversion between formats for the use with the clipboard.
* Some terminology:
* "native" format - the format understood by Wayland; MIME with some deviations
* "long" format - an arbintrary number assigned to some native format;
* once established, this mapping never changes
*/
public class WLDataTransferer extends DataTransferer {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.WLDataTransferer");
private static ImageTypeSpecifier defaultImageSpec = null;
// Maps the "native" format (MIME) to its numeric ID
private final Map<String, Long> nameToLong = new HashMap<>();
// Maps the numeric ID of a format to its native (MIME) representation
private final Map<Long, String> longToName = new HashMap<>();
private final Map<Long, Boolean> imageFormats = new HashMap<>();
private final Map<Long, Boolean> textFormats = new HashMap<>();
private static class HOLDER {
static WLDataTransferer instance = new WLDataTransferer();
}
static WLDataTransferer getInstanceImpl() {
return HOLDER.instance;
}
@Override
public String getDefaultUnicodeEncoding() {
return "UTF-8";
}
@Override
public boolean isLocaleDependentTextFormat(long format) {
return false;
}
@Override
public boolean isFileFormat(long format) {
String nat = getNativeForFormat(format);
return "FILE_NAME".equals(nat);
}
@Override
public boolean isImageFormat(long format) {
synchronized (this) {
return imageFormats.computeIfAbsent(format, f -> isMimeFormat(f, "image"));
}
}
@Override
public boolean isTextFormat(long format) {
synchronized (this) {
return textFormats.computeIfAbsent(
format,
f -> super.isTextFormat(format)
|| isMimeFormat(format, "text"));
}
}
/**
* @return true if the given format ID corresponds to a MIME format
* with the given primary type
*/
private boolean isMimeFormat(long format, String primaryType) {
String nat = getNativeForFormat(format);
if (nat != null) {
try {
DataFlavor df = new DataFlavor(nat);
if (primaryType.equals(df.getPrimaryType())) {
return true;
}
} catch (Exception ignored) { /* Not MIME */ }
}
return false;
}
@Override
protected Long getFormatForNativeAsLong(String formatName) {
Objects.requireNonNull(formatName);
synchronized (this) {
Long thisID = nameToLong.get(formatName);
if (thisID == null) {
// Some apps request data in a format that only differs from
// the advertised in the case of some of the letters.
// IMO we can ignore the case and find an equivalent.
var matchingKey = nameToLong.keySet().stream()
.filter(formatName::equalsIgnoreCase).findAny()
.orElse(null);
if (matchingKey != null) {
thisID = nameToLong.get(matchingKey);
} else {
long nextID = nameToLong.size();
thisID = nextID;
longToName.put(thisID, formatName);
}
nameToLong.put(formatName, thisID);
}
return thisID;
}
}
@Override
protected String getNativeForFormat(long format) {
synchronized (this) {
return longToName.get(format);
}
}
@Override
protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < fileList.size(); i++) {
byte[] bytes = fileList.get(i).getBytes();
if (i != 0) bos.write(0);
bos.write(bytes, 0, bytes.length);
}
return bos;
}
@Override
protected String[] dragQueryFile(byte[] bytes) {
// TODO
log.info("Unimplemented");
return new String[0];
}
@Override
protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException {
DataFlavor df = getImageDataFlavorForFormat(format);
final String baseType = df.getPrimaryType() + "/" + df.getSubType();
Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(baseType);
BufferedImage bi = null;
if (readers.hasNext()) {
ImageReader reader = readers.next();
ImageReadParam param = reader.getDefaultReadParam();
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
ImageInputStream stream = ImageIO.createImageInputStream(byteStream);
reader.setInput(stream, true, true);
try (stream) {
bi = reader.read(0, param);
} finally {
reader.dispose();
}
}
return bi;
}
@Override
protected byte[] imageToPlatformBytes(Image image, long format) throws IOException {
int width = image.getWidth(null);
int height = image.getHeight(null);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
int numBytes = (int)(width * height * bufferedImage.getColorModel().getPixelSize() / 8.0);
ByteArrayOutputStream out = new ByteArrayOutputStream(numBytes);
DataFlavor df = getImageDataFlavorForFormat(format);
ImageIO.write(bufferedImage, df.getSubType(), out);
return out.toByteArray();
}
private DataFlavor getImageDataFlavorForFormat(long format) {
String nat = getNativeForFormat(format);
DataFlavor df = null;
try {
df = new DataFlavor(nat);
} catch (Exception ignored) { }
if (df == null) {
throw new InternalError("Native image format " + nat + " corresponding to ID "
+ format + " not recognized as DataFlavor");
}
return df;
}
@Override
public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
return WLToolkitThreadBlockedHandler.getToolkitThreadBlockedHandler();
}
@Override
public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) {
// TODO: much of this has been taken verbatim from XDataTransferer.
// Worth refactoring the common stuff out?
LinkedHashSet<DataFlavor> flavors = new LinkedHashSet<>();
if (nat == null) {
return flavors;
}
DataFlavor df;
try {
df = new DataFlavor(nat);
} catch (Exception e) {
// The string doesn't constitute a valid MIME type.
return flavors;
}
DataFlavor value = df;
final String primaryType = df.getPrimaryType();
// For text formats we map natives to MIME strings instead of data
// flavors to enable dynamic text native-to-flavor mapping generation.
// See SystemFlavorMap.getFlavorsForNative() for details.
if ("image".equals(primaryType)) {
final String baseType = primaryType + "/" + df.getSubType();
Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(baseType);
if (readers.hasNext()) {
flavors.add(DataFlavor.imageFlavor);
}
}
flavors.add(value);
return flavors;
}
private ImageTypeSpecifier getDefaultImageTypeSpecifier() {
if (defaultImageSpec == null) {
ColorModel model = ColorModel.getRGBdefault();
WritableRaster raster =
model.createCompatibleWritableRaster(10, 10);
BufferedImage bufferedImage =
new BufferedImage(model, raster, model.isAlphaPremultiplied(),
null);
defaultImageSpec = new ImageTypeSpecifier(bufferedImage);
}
return defaultImageSpec;
}
@Override
public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) {
LinkedHashSet<String> natives = new LinkedHashSet<>(1);
if (df == null) {
return natives;
}
String charset = df.getParameter("charset");
String baseType = df.getPrimaryType() + "/" + df.getSubType();
String mimeType = baseType;
if (charset != null && DataFlavorUtil.isFlavorCharsetTextType(df)) {
mimeType += ";charset=" + charset;
}
// Add a mapping to the MIME native whenever the representation class
// doesn't require translation.
if (df.getRepresentationClass() != null &&
(df.isRepresentationClassInputStream() ||
df.isRepresentationClassByteBuffer() ||
byte[].class.equals(df.getRepresentationClass()))) {
natives.add(mimeType);
}
if (DataFlavor.imageFlavor.equals(df)) {
String[] mimeTypes = ImageIO.getWriterMIMETypes();
if (mimeTypes != null) {
for (String mime : mimeTypes) {
Iterator<ImageWriter> writers = ImageIO.getImageWritersByMIMEType(mime);
while (writers.hasNext()) {
ImageWriter imageWriter = writers.next();
ImageWriterSpi writerSpi = imageWriter.getOriginatingProvider();
if (writerSpi != null &&
writerSpi.canEncodeImage(getDefaultImageTypeSpecifier())) {
natives.add(mime);
break;
}
}
}
}
} else if (DataFlavorUtil.isFlavorCharsetTextType(df)) {
// stringFlavor is semantically equivalent to the standard
// "text/plain" MIME type.
if (DataFlavor.stringFlavor.equals(df)) {
baseType = "text/plain";
}
for (String encoding : DataFlavorUtil.standardEncodings()) {
if (!encoding.equals(charset)) {
natives.add(baseType + ";charset=" + encoding);
}
}
// Add a MIME format without specified charset.
natives.add(baseType);
}
return natives;
}
}

View File

@@ -134,9 +134,11 @@ public abstract class WLDecoratedPeer extends WLWindowPeer {
}
void postPaintEvent() {
// Full re-paint must include window decorations, if any
notifyClientDecorationsChanged();
super.postPaintEvent();
if (isVisible()) {
// Full re-paint must include window decorations, if any
notifyClientDecorationsChanged();
super.postPaintEvent();
}
}
final void paintClientDecorations(final Graphics g) {

View File

@@ -127,11 +127,6 @@ public class WLFramePeer extends WLDecoratedPeer implements FramePeer {
throw new UnsupportedOperationException();
}
@Override
public void toFront() {
//throw new UnsupportedOperationException();
}
@Override
public void toBack() {
throw new UnsupportedOperationException();

View File

@@ -73,10 +73,9 @@ public abstract class WLGraphicsConfig extends GraphicsConfiguration {
@Override
public AffineTransform getNormalizingTransform() {
// TODO: may not be able to implement this fully, but we can try
// obtaining physical width/height from wl_output.geometry event.
// Those may be 0, of course.
return getDefaultTransform();
double xScale = device.getResolutionX(this) / 72.0;
double yScale = device.getResolutionY(this) / 72.0;
return new AffineTransform(xScale, 0.0, 0.0, yScale, 0.0, 0.0);
}
@Override

View File

@@ -31,6 +31,7 @@ import sun.java2d.vulkan.WLVKGraphicsConfig;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Window;
@@ -39,6 +40,7 @@ import java.awt.Window;
* in the multi-monitor setup. Whenever those change, this device is re-created.
*/
public class WLGraphicsDevice extends GraphicsDevice {
private static final double MM_IN_INCH = 25.4;
/**
* ID of the corresponding wl_output object received from Wayland.
*/
@@ -60,16 +62,21 @@ public class WLGraphicsDevice extends GraphicsDevice {
*/
private volatile int y; // only changes when the device gets invalidated
private final int widthMm;
private final int heightMm;
// Configs are always the same in size and scale
private volatile WLGraphicsConfig[] configs = null;
private volatile GraphicsConfiguration[] configs = null;
// The default config is an object from the configs array
private volatile WLGraphicsConfig defaultConfig = null;
private WLGraphicsDevice(int id, int x, int y) {
private WLGraphicsDevice(int id, int x, int y, int widthMm, int heightMm) {
this.wlID = id;
this.x = x;
this.y = y;
this.widthMm = widthMm;
this.heightMm = heightMm;
}
int getID() {
@@ -77,23 +84,30 @@ public class WLGraphicsDevice extends GraphicsDevice {
}
void updateConfiguration(String name, int width, int height, int scale) {
this.name = name == null ? "wl_output." + wlID : name;
this.name = name;
if (configs == null || configs[0].differsFrom(width, height, scale)) {
WLGraphicsConfig config = defaultConfig;
// Note that all configs are of equal size and scale
if (config == null || config.differsFrom(width, height, scale)) {
GraphicsConfiguration[] newConfigs;
WLGraphicsConfig newDefaultConfig;
// It is necessary to create a new object whenever config changes as its
// identity is used to detect changes in scale, among other things.
if (WLGraphicsEnvironment.isVulkanEnabled()) {
defaultConfig = WLVKGraphicsConfig.getConfig(this, width, height, scale);
configs = new WLGraphicsConfig[1];
configs[0] = defaultConfig;
newDefaultConfig = WLVKGraphicsConfig.getConfig(this, width, height, scale);
newConfigs = new GraphicsConfiguration[1];
newConfigs[0] = newDefaultConfig;
} else {
// TODO: Actually, Wayland may support a lot more shared memory buffer configurations, need to
// subscribe to the wl_shm:format event and get the list from there.
defaultConfig = WLSMGraphicsConfig.getConfig(this, width, height, scale, false);
configs = new WLGraphicsConfig[2];
configs[0] = defaultConfig;
configs[1] = WLSMGraphicsConfig.getConfig(this, width, height, scale, true);
newDefaultConfig = WLSMGraphicsConfig.getConfig(this, width, height, scale, false);
newConfigs = new GraphicsConfiguration[2];
newConfigs[0] = newDefaultConfig;
newConfigs[1] = WLSMGraphicsConfig.getConfig(this, width, height, scale, true);
}
configs = newConfigs;
defaultConfig = newDefaultConfig;
}
}
@@ -107,13 +121,17 @@ public class WLGraphicsDevice extends GraphicsDevice {
this.x = similarDevice.x;
this.y = similarDevice.y;
final int newScale = similarDevice.getScale();
final Rectangle newBounds = similarDevice.defaultConfig.getBounds();
int newScale = similarDevice.getScale();
Rectangle newBounds = similarDevice.defaultConfig.getBounds();
updateConfiguration(similarDevice.name, newBounds.width, newBounds.height, newScale);
}
public static WLGraphicsDevice createWithConfiguration(int id, String name, int x, int y, int width, int height, int scale) {
final WLGraphicsDevice device = new WLGraphicsDevice(id, x, y);
public static WLGraphicsDevice createWithConfiguration(int id, String name,
int x, int y,
int width, int height,
int widthMm, int heightMm,
int scale) {
WLGraphicsDevice device = new WLGraphicsDevice(id, x, y, widthMm, heightMm);
device.updateConfiguration(name, width, height, scale);
return device;
}
@@ -127,11 +145,17 @@ public class WLGraphicsDevice extends GraphicsDevice {
}
boolean hasSameNameAs(WLGraphicsDevice otherDevice) {
return name != null && otherDevice.name != null && name.equals(otherDevice.name);
var localName = name;
var otherName = otherDevice.name;
return localName != null && localName.equals(otherName);
}
boolean hasSameSizeAs(WLGraphicsDevice modelDevice) {
return defaultConfig != null && modelDevice.defaultConfig != null && defaultConfig.getBounds().equals(modelDevice.defaultConfig.getBounds());
var config = defaultConfig;
var modelConfig = modelDevice.defaultConfig;
return config != null
&& modelConfig != null
&& config.getBounds().equals(modelConfig.getBounds());
}
@Override
@@ -163,6 +187,27 @@ public class WLGraphicsDevice extends GraphicsDevice {
return defaultConfig.getScale();
}
int getResolution() {
Rectangle bounds = defaultConfig.getBounds();
if (bounds.width == 0 || bounds.height == 0) return 0;
double diagonalPixel = Math.sqrt(bounds.width * bounds.width + bounds.height * bounds.height);
double diagonalMm = Math.sqrt(widthMm * widthMm + heightMm * heightMm);
return (int) (diagonalPixel / diagonalMm * MM_IN_INCH);
}
int getResolutionX(WLGraphicsConfig config) {
Rectangle bounds = config.getBounds();
if (bounds.width == 0) return 0;
return (int)((double)bounds.width / widthMm * MM_IN_INCH);
}
int getResolutionY(WLGraphicsConfig config) {
Rectangle bounds = config.getBounds();
if (bounds.height == 0) return 0;
return (int)((double)bounds.height / heightMm * MM_IN_INCH);
}
@Override
public boolean isFullScreenSupported() {
return true;
@@ -211,8 +256,13 @@ public class WLGraphicsDevice extends GraphicsDevice {
@Override
public String toString() {
return String.format("WLGraphicsDevice: id=%d at (%d, %d) with %s",
wlID, x, y,
defaultConfig != null ? defaultConfig : "<no configs>");
var config = defaultConfig;
return String.format("WLGraphicsDevice: '%s' id=%d at (%d, %d) with %s",
name, wlID, x, y,
config != null ? config : "<no configs>");
}
public Insets getInsets() {
return new Insets(0, 0, 0, 0);
}
}

View File

@@ -45,23 +45,43 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.wl.WLGraphicsEnvironment");
private static boolean vulkanEnabled = false;
private static boolean verboseVulkanStatus = false;
private static boolean vulkanRequested = false;
private static int vulkanRequestedDeviceNumber = -1;
@SuppressWarnings("removal")
private static boolean vulkanRequested =
private static String vulkanOption =
AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () ->
"true".equals(System.getProperty("sun.java2d.vulkan")));
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan", ""));
@SuppressWarnings("removal")
private static String vulkanOptionDeviceNumber =
AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.deviceNumber", "0"));
static {
vulkanRequested = "true".equalsIgnoreCase(vulkanOption);
try {
vulkanRequestedDeviceNumber = Integer.parseInt(vulkanOptionDeviceNumber);
} catch (NumberFormatException e) {
log.warning("Invalid Vulkan device number:" + vulkanOptionDeviceNumber);
}
verboseVulkanStatus = "True".equals(vulkanOption);
System.loadLibrary("awt");
SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
if (vulkanRequested) {
vulkanEnabled = initVKWL();
vulkanEnabled = initVKWL(verboseVulkanStatus, vulkanRequestedDeviceNumber);
}
if (log.isLoggable(Level.FINE)) {
log.fine("Vulkan rendering enabled: " + (vulkanEnabled?"YES":"NO"));
}
// Make sure the toolkit is loaded because otherwise this GE is going to be empty
WLToolkit.isInitialized();
}
private static native boolean initVKWL();
private static native boolean initVKWL(boolean verbose, int deviceNumber);
private WLGraphicsEnvironment() {
}
@@ -100,7 +120,8 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
private final List<WLGraphicsDevice> devices = new ArrayList<>(5);
private void notifyOutputConfigured(String name, int wlID, int x, int y, int width, int height,
private void notifyOutputConfigured(String name, String make, String model, int wlID,
int x, int y, int width, int height, int widthMm, int heightMm,
int subpixel, int transform, int scale) {
// Called from native code whenever a new output appears or an existing one changes its properties
// NB: initially called during WLToolkit.initIDs() on the main thread; later on EDT.
@@ -108,6 +129,10 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
log.fine(String.format("Output configured id=%d at (%d, %d) %dx%d %dx scale", wlID, x, y, width, height, scale));
}
String humanID =
(name != null ? name + " " : "")
+ (make != null ? make + " " : "")
+ (model != null ? model : "");
synchronized (devices) {
boolean newOutput = true;
for (int i = 0; i < devices.size(); i++) {
@@ -115,9 +140,10 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
if (gd.getID() == wlID) {
newOutput = false;
if (gd.isSameDeviceAs(wlID, x, y)) {
gd.updateConfiguration(name, width, height, scale);
gd.updateConfiguration(humanID, width, height, scale);
} else {
final WLGraphicsDevice updatedDevice = WLGraphicsDevice.createWithConfiguration(wlID, name, x, y, width, height, scale);
final WLGraphicsDevice updatedDevice = WLGraphicsDevice.createWithConfiguration(wlID, humanID,
x, y, width, height, widthMm, heightMm, scale);
devices.set(i, updatedDevice);
gd.invalidate(updatedDevice);
}
@@ -125,7 +151,8 @@ public class WLGraphicsEnvironment extends SunGraphicsEnvironment {
}
}
if (newOutput) {
final WLGraphicsDevice gd = WLGraphicsDevice.createWithConfiguration(wlID, name, x, y, width, height, scale);
final WLGraphicsDevice gd = WLGraphicsDevice.createWithConfiguration(wlID, humanID, x, y,
width, height, widthMm, heightMm, scale);
devices.add(gd);
}
}

View File

@@ -35,7 +35,8 @@ public class WLKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
@Override
public void setCurrentFocusOwner(Component comp) {
if (comp != currentFocusedWindow) {
if (comp != null && (!(comp instanceof Window window) ||
WLComponentPeer.getNativelyFocusableOwnerOrSelf(window) != currentFocusedWindow)) {
// In Wayland, only Window can be focused, not any widget in it.
focusLog.severe("Unexpected focus owner set in a Window: " + comp);
}

View File

@@ -28,6 +28,8 @@ package sun.awt.wl;
import jdk.internal.misc.InnocuousThread;
import sun.awt.AWTAccessor;
import sun.awt.AWTAutoShutdown;
import sun.awt.AWTPermissions;
import sun.awt.AppContext;
import sun.awt.LightweightFrame;
import sun.awt.PeerEvent;
@@ -85,6 +87,7 @@ import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;
@@ -137,6 +140,9 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
private static final int NUM_LOCK_MASK = 0x02;
private static boolean initialized = false;
private static Thread toolkitThread;
private final WLClipboard clipboard;
private final WLClipboard selection;
private static native void initIDs();
@@ -158,7 +164,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
});
if (!GraphicsEnvironment.isHeadless()) {
Thread toolkitThread = InnocuousThread.newThread("AWT-Wayland", this);
toolkitThread = InnocuousThread.newThread("AWT-Wayland", this);
toolkitThread.setDaemon(true);
toolkitThread.start();
@@ -166,10 +172,24 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
toolkitSystemThread.setDaemon(true);
toolkitSystemThread.start();
// Wait here for all display sync events to have been received?
WLClipboard selectionClipboard = null;
try {
selectionClipboard = new WLClipboard("Selection", true);
} catch (UnsupportedOperationException ignored) {
}
clipboard = new WLClipboard("System", false);
selection = selectionClipboard;
} else {
clipboard = null;
selection = null;
}
}
public static boolean isToolkitThread() {
return Thread.currentThread() == toolkitThread;
}
@Override
public ButtonPeer createButton(Button target) {
ButtonPeer peer = new WLButtonPeer(target);
@@ -204,12 +224,14 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public void run() {
while(true) {
AWTAutoShutdown.notifyToolkitThreadFree(); // will now wait for events
int result = readEvents();
if (result == READ_RESULT_ERROR) {
log.severe("Wayland protocol I/O error");
// TODO: display disconnect handling here?
break;
} else if (result == READ_RESULT_FINISHED_WITH_EVENTS) {
AWTAutoShutdown.notifyToolkitThreadBusy(); // busy processing events
SunToolkit.postEvent(AppContext.getAppContext(), new PeerEvent(this, () -> {
WLToolkit.awtLock();
try {
@@ -234,7 +256,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
* the next click is considered separate and not part of multi-click event.
* @return maximum milliseconds between same mouse button clicks for them to be a multiclick
*/
static long getMulticlickTime() {
static int getMulticlickTime() {
/* TODO: get from the system somehow */
return AWT_MULTICLICK_DEFAULT_TIME_MS;
}
@@ -748,8 +770,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public DataTransferer getDataTransferer() {
log.info("Not implemented: WLToolkit.getDataTransferer()");
return null;
return WLDataTransferer.getInstanceImpl();
}
@Override
@@ -781,14 +802,23 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public Clipboard getSystemClipboard() {
log.info("Not implemented: WLToolkit.getSystemClipboard()");
return null;
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION);
}
return clipboard;
}
@Override
public Clipboard getSystemSelection() {
log.info("Not implemented: WLToolkit.getSystemSelection()");
return null;
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION);
}
return selection;
}
@Override
@@ -814,8 +844,8 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public int getScreenResolution() {
// TODO
return 150;
var defaultScreen = (WLGraphicsDevice)WLGraphicsEnvironment.getSingleInstance().getDefaultScreenDevice();
return defaultScreen.getResolution();
}
/**
@@ -855,8 +885,14 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
protected void initializeDesktopProperties() {
super.initializeDesktopProperties();
desktopProperties.put("DnD.Autoscroll.initialDelay", 50);
desktopProperties.put("DnD.Autoscroll.interval", 50);
desktopProperties.put("DnD.Autoscroll.cursorHysteresis", 5);
desktopProperties.put("Shell.shellFolderManager", "sun.awt.shell.ShellFolderManager");
if (!GraphicsEnvironment.isHeadless()) {
desktopProperties.put("awt.mouse.numButtons", MOUSE_BUTTONS_COUNT);
desktopProperties.put("awt.multiClickInterval", getMulticlickTime());
desktopProperties.put("awt.mouse.numButtons", getNumberOfButtons());
}
}
@@ -996,6 +1032,17 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
flushImpl();
}
@Override
public Insets getScreenInsets(final GraphicsConfiguration gc) {
final GraphicsDevice gd = gc.getDevice();
if (gd instanceof WLGraphicsDevice device) {
Insets insets = device.getInsets();
return (Insets) insets.clone();
} else {
return super.getScreenInsets(gc);
}
}
private native int readEvents();
private native void dispatchEventsOnEDT();
private native void flushImpl();

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt.wl;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
// TODO: this class is essentially unused; not sure if it even has to be here
final class WLToolkitThreadBlockedHandler implements
ToolkitThreadBlockedHandler {
private static final ToolkitThreadBlockedHandler privilegedLock = new WLToolkitThreadBlockedHandler();
private static final WLToolkit tk = (WLToolkit) java.awt.Toolkit.getDefaultToolkit();
private WLToolkitThreadBlockedHandler() {
}
static ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
return privilegedLock;
}
public void lock() {
throw new UnsupportedOperationException();
}
public void unlock() {
throw new UnsupportedOperationException();
}
public void enter() {
throw new UnsupportedOperationException();
}
public void exit() {
throw new UnsupportedOperationException();
}
}

View File

@@ -26,11 +26,13 @@ package sun.awt.wl;
import sun.awt.AWTAccessor;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.peer.ComponentPeer;
import java.awt.peer.WindowPeer;
public class WLWindowPeer extends WLComponentPeer implements WindowPeer {
private static Font defaultFont;
private Dialog blocker;
static synchronized Font getDefaultFont() {
if (null == defaultFont) {
@@ -55,14 +57,29 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer {
@Override
protected void wlSetVisible(boolean v) {
if (v && targetIsWlPopup() && shouldBeFocusedOnShowing()) {
requestWindowFocus();
}
super.wlSetVisible(v);
final AWTAccessor.ComponentAccessor acc = AWTAccessor.getComponentAccessor();
for (Component c : ((Window)target).getComponents()) {
for (Component c : getWindow().getComponents()) {
ComponentPeer cPeer = acc.getPeer(c);
if (cPeer instanceof WLComponentPeer) {
((WLComponentPeer) cPeer).wlSetVisible(v);
}
}
if (!v && targetIsWlPopup() && getWindow().isFocused()) {
Window targetOwner = getWindow().getOwner();
while (targetOwner != null && (targetOwner.getOwner() != null && !targetOwner.isFocusableWindow())) {
targetOwner = targetOwner.getOwner();
}
if (targetOwner != null) {
WLWindowPeer wndpeer = AWTAccessor.getComponentAccessor().getPeer(targetOwner);
if (wndpeer != null) {
wndpeer.requestWindowFocus();
}
}
}
}
@Override
@@ -89,7 +106,7 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer {
@Override
public void toFront() {
// TODO
activate();
}
@Override
@@ -109,7 +126,7 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer {
@Override
public void setModalBlocked(Dialog blocker, boolean blocked) {
this.blocker = blocked ? blocker : null;
}
@Override
@@ -150,4 +167,25 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer {
public void repositionSecurityWarning() {
throw new UnsupportedOperationException();
}
private Window getWindow() {
return (Window) target;
}
private boolean shouldBeFocusedOnShowing() {
Window window = getWindow();
return window.isFocusableWindow() &&
window.isAutoRequestFocus() &&
blocker == null;
}
// supporting only 'synthetic' focus transfers for now (when natively focused window stays the same)
private void requestWindowFocus() {
Window window = getWindow();
Window nativeFocusTarget = getNativelyFocusableOwnerOrSelf(window);
if (nativeFocusTarget != null &&
WLKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == nativeFocusTarget) {
WLToolkit.postEvent(new WindowEvent(window, WindowEvent.WINDOW_GAINED_FOCUS));
}
}
}

View File

@@ -67,7 +67,6 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
PlatformLogger.getLogger("sun.java2d.vulkan.WLVKGraphicsConfig");
private static ImageCapabilities imageCaps = new VKImageCaps();
private final int maxTextureSize;
private BufferCapabilities bufferCaps;
private ContextCapabilities vkCaps;
@@ -75,17 +74,9 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
private static native long getVKConfigInfo();
/**
* Returns maximum texture size supported by Vulkan. Must be
* called under VKRQ lock.
*/
private static native int nativeGetMaxTextureSize();
public WLVKGraphicsConfig(WLGraphicsDevice device, int width, int height, int scale, int maxTextureSize,
ContextCapabilities vkCaps) {
public WLVKGraphicsConfig(WLGraphicsDevice device, int width, int height, int scale, ContextCapabilities vkCaps) {
super(device, width, height, scale);
this.vkCaps = vkCaps;
this.maxTextureSize = maxTextureSize;
context = new VKContext(VKRenderQueue.getInstance());
}
@@ -100,7 +91,7 @@ public final class WLVKGraphicsConfig extends WLGraphicsConfig
CAPS_PS30 | CAPS_PS20 | CAPS_RT_TEXTURE_ALPHA |
CAPS_RT_TEXTURE_OPAQUE | CAPS_MULTITEXTURE | CAPS_TEXNONPOW2 |
CAPS_TEXNONSQUARE, null);
return new WLVKGraphicsConfig(device, width, height, scale, nativeGetMaxTextureSize(), caps);
return new WLVKGraphicsConfig(device, width, height, scale, caps);
}
/**

View File

@@ -44,7 +44,6 @@ public abstract class WLVKSurfaceData extends VKSurfaceData implements WLSurface
protected WLComponentPeer peer;
protected WLVKGraphicsConfig graphicsConfig;
private native void initOps(WLVKGraphicsConfig gc, WLComponentPeer peer);
@Override
public native void assignSurface(long surfacePtr);

View File

@@ -27,12 +27,4 @@
#include "jni.h"
#include "VKBase.h"
/*
* Class: sun_java2d_vulkan_WLVKGraphicsConfig
* Method: nativeGetMaxTextureSize
* Signature: ()I
*/
extern "C" JNIEXPORT jint JNICALL Java_sun_java2d_vulkan_WLVKGraphicsConfig_nativeGetMaxTextureSize
(JNIEnv *env, jclass vkgc) {
return VK_MaxTextureSize();
}
// TODO ?

View File

@@ -36,121 +36,32 @@
extern struct wl_display *wl_display;
/**
* This is the implementation of the general surface LockFunc defined in
* SurfaceData.h.
*/
jint
WLVKSD_Lock(JNIEnv *env,
SurfaceDataOps *ops,
SurfaceDataRasInfo *pRasInfo,
jint lockflags)
{
#ifndef HEADLESS
VKSDOps *vsdo = (VKSDOps*)ops;
J2dTrace1(J2D_TRACE_INFO, "WLVKSD_Unlock: %p\n", ops);
pthread_mutex_lock(&((WLVKSDOps*)vsdo->privOps)->lock);
#endif
return SD_SUCCESS;
}
static void
WLVKSD_GetRasInfo(JNIEnv *env,
SurfaceDataOps *ops,
SurfaceDataRasInfo *pRasInfo)
{
#ifndef HEADLESS
VKSDOps *vsdo = (VKSDOps*)ops;
#endif
}
static void
WLVKSD_Unlock(JNIEnv *env,
SurfaceDataOps *ops,
SurfaceDataRasInfo *pRasInfo)
{
#ifndef HEADLESS
VKSDOps *vsdo = (VKSDOps*)ops;
J2dTrace1(J2D_TRACE_INFO, "WLVKSD_Unlock: %p\n", ops);
pthread_mutex_unlock(&((WLVKSDOps*)vsdo->privOps)->lock);
#endif
}
static void
WLVKSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
{
#ifndef HEADLESS
/* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
VKSDOps *vsdo = (VKSDOps*)ops;
J2dTrace1(J2D_TRACE_INFO, "WLSD_Dispose %p\n", ops);
WLVKSDOps *wlvksdOps = (WLVKSDOps*)vsdo->privOps;
pthread_mutex_destroy(&wlvksdOps->lock);
if (wlvksdOps->wlvkSD !=nullptr) {
delete wlvksdOps->wlvkSD;
wlvksdOps->wlvkSD = nullptr;
}
#endif
}
extern "C" JNIEXPORT void JNICALL Java_sun_java2d_vulkan_WLVKSurfaceData_initOps
(JNIEnv *env, jclass vksd, jint width, jint height, jint scale, jint backgroundRGB) {
(JNIEnv *env, jobject vksd, jint width, jint height, jint scale, jint backgroundRGB) {
#ifndef HEADLESS
VKSDOps *vsdo = (VKSDOps*)SurfaceData_InitOps(env, vksd, sizeof(VKSDOps));
J2dRlsTraceLn1(J2D_TRACE_INFO, "WLVKSurfaceData_initOps: %p", vsdo);
jboolean hasException;
if (vsdo == NULL) {
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
return;
}
if (width <= 0) {
width = 1;
}
if (height <= 0) {
height = 1;
}
WLVKSDOps *wlvksdOps = (WLVKSDOps *)malloc(sizeof(WLVKSDOps));
if (wlvksdOps == NULL) {
JNU_ThrowOutOfMemoryError(env, "creating native WLVK ops");
return;
}
vsdo->privOps = wlvksdOps;
vsdo->sdOps.Lock = WLVKSD_Lock;
vsdo->sdOps.Unlock = WLVKSD_Unlock;
vsdo->sdOps.GetRasInfo = WLVKSD_GetRasInfo;
vsdo->sdOps.Dispose = WLVKSD_Dispose;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
// Recursive mutex is required because blit can be done with both source
// and destination being the same surface (during scrolling, for example).
// So WLSD_Lock() should be able to lock the same surface twice in a row.
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&wlvksdOps->lock, &attr);
wlvksdOps->wlvkSD = new WLVKSurfaceData(width, height, scale, backgroundRGB);
J2dTrace3(J2D_TRACE_INFO, "Create WLVKSurfaceData with size %d x %d and scale %d\n", width, height, scale);
width /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
height /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
auto *sd = new WLVKSurfaceData(width, height, scale, backgroundRGB);
sd->attachToJavaSurface(env, vksd);
#endif /* !HEADLESS */
}
extern "C" JNIEXPORT void JNICALL
Java_sun_java2d_vulkan_WLVKSurfaceData_assignSurface(JNIEnv *env, jobject wsd,
jlong wlSurfacePtr)
Java_sun_java2d_vulkan_WLVKSurfaceData_assignSurface(JNIEnv *env, jobject wsd, jlong wlSurfacePtr)
{
#ifndef HEADLESS
VKSDOps *vsdo = (VKSDOps*)SurfaceData_GetOps(env, wsd);
if (vsdo == NULL) {
auto sd = (WLVKSurfaceData*)SurfaceData_GetOps(env, wsd);
if (sd == nullptr) {
return;
}
WLVKSDOps *wlvksdOps = (WLVKSDOps*)vsdo->privOps;
wl_surface* wlSurface = (struct wl_surface*)jlong_to_ptr(wlSurfacePtr);
auto wlSurface = (struct wl_surface*)jlong_to_ptr(wlSurfacePtr);
J2dTraceLn2(J2D_TRACE_INFO, "WLVKSurfaceData_assignSurface wl_surface(%p) wl_display(%p)",
wlSurface, wl_display);
try {
wlvksdOps->wlvkSD->validate(wlSurface);
sd->validate(wlSurface);
} catch (std::exception& e) {
J2dRlsTrace1(J2D_TRACE_ERROR, "WLVKSurfaceData_assignSurface: %s\n", e.what());
}
@@ -162,6 +73,7 @@ Java_sun_java2d_vulkan_WLVKSurfaceData_flush(JNIEnv *env, jobject wsd)
{
#ifndef HEADLESS
J2dTrace(J2D_TRACE_INFO, "WLVKSurfaceData_flush\n");
// TODO?
#endif /* !HEADLESS */
}
@@ -169,17 +81,17 @@ extern "C" JNIEXPORT void JNICALL
Java_sun_java2d_vulkan_WLVKSurfaceData_revalidate(JNIEnv *env, jobject wsd,
jint width, jint height, jint scale)
{
width /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
height /= scale; // TODO This is incorrect, but we'll deal with this later, we probably need to do something on Wayland side for app-controlled scaling
#ifndef HEADLESS
VKSDOps *vsdo = (VKSDOps*)SurfaceData_GetOps(env, wsd);
if (vsdo == NULL) {
auto sd = (WLVKSurfaceData*)SurfaceData_GetOps(env, wsd);
if (sd == nullptr) {
return;
}
J2dTrace3(J2D_TRACE_INFO, "WLVKSurfaceData_revalidate to size %d x %d and scale %d\n", width, height, scale);
WLVKSDOps *wlvksdOps = (WLVKSDOps*)vsdo->privOps;
try {
wlvksdOps->wlvkSD->revalidate(width, height, scale);
wlvksdOps->wlvkSD->update();
sd->revalidate(width, height, scale);
} catch (std::exception& e) {
J2dRlsTrace1(J2D_TRACE_ERROR, "WLVKSurfaceData_revalidate: %s\n", e.what());
}
@@ -187,153 +99,18 @@ Java_sun_java2d_vulkan_WLVKSurfaceData_revalidate(JNIEnv *env, jobject wsd,
#endif /* !HEADLESS */
}
extern "C" JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM *vm, void *reserved) {
#ifndef HEADLESS
VKGraphicsEnvironment::dispose();
#endif /* !HEADLESS */
}
WLVKSurfaceData::WLVKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
:VKSurfaceData(w, h, s, bgc), _wl_surface(nullptr), _surface_khr(nullptr), _swapchain_khr(nullptr)
{
J2dTrace3(J2D_TRACE_INFO, "Create WLVKSurfaceData with size %d x %d and scale %d\n", w, h, s);
}
void WLVKSurfaceData::validate(wl_surface* wls)
{
if (wls ==_wl_surface) {
return;
}
auto& device = VKGraphicsEnvironment::graphics_environment()->default_device();
device.waitIdle(); // TODO wait until device is done with old swapchain
auto surface = VKGraphicsEnvironment::graphics_environment()->vk_instance()
.createWaylandSurfaceKHR({{}, wl_display, wls});
_wl_surface = wls;
vk::WaylandSurfaceCreateInfoKHR createInfoKhr = {
{}, wl_display, _wl_surface
};
_surface_khr =
VKGraphicsEnvironment::graphics_environment()->vk_instance().createWaylandSurfaceKHR(
createInfoKhr);
reset(device, std::move(surface));
revalidate(width(), height(), scale());
update();
}
void WLVKSurfaceData::revalidate(uint32_t w, uint32_t h, uint32_t s)
{
if (s == scale() && w == width() && h == height() ) {
if (!*_surface_khr || *_swapchain_khr) {
J2dTraceLn2(J2D_TRACE_INFO,
"WLVKSurfaceData_revalidate is skipped: surface_khr(%p) swapchain_khr(%p)",
*_surface_khr, *_swapchain_khr);
return;
}
} else {
VKSurfaceData::revalidate(w, h, s);
if (!*_surface_khr) {
J2dTraceLn1(J2D_TRACE_INFO,"WLVKSurfaceData_revalidate is skipped: surface_khr(%p)",
*_surface_khr);
return;
}
}
vk::SwapchainCreateInfoKHR swapchainCreateInfoKhr{
{},
*_surface_khr,
1, vk::Format::eB8G8R8A8Unorm,
vk::ColorSpaceKHR::eVkColorspaceSrgbNonlinear,
{width()/scale(), height()/scale()},
1,
vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst,
vk::SharingMode::eExclusive,
0,
nullptr,
vk::SurfaceTransformFlagBitsKHR::eIdentity,
vk::CompositeAlphaFlagBitsKHR::eOpaque,
vk::PresentModeKHR::eImmediate,
false, *_swapchain_khr
};
auto& device = VKGraphicsEnvironment::graphics_environment()->default_device();
_swapchain_khr = device.createSwapchainKHR(swapchainCreateInfoKhr);
}
void WLVKSurfaceData::set_bg_color(uint32_t bgc)
{
if (bg_color() == bgc) {
return;
}
VKSurfaceData::set_bg_color(bgc);
update();
}
void WLVKSurfaceData::update()
{
if (!*_swapchain_khr) {
return;
}
auto& device = VKGraphicsEnvironment::graphics_environment()->default_device();
vk::SemaphoreCreateInfo semInfo = {};
vk::raii::Semaphore presentCompleteSem = device.createSemaphore(semInfo);
std::pair<vk::Result, uint32_t> img = _swapchain_khr.acquireNextImage(0, *presentCompleteSem, nullptr);
if (img.first!=vk::Result::eSuccess) {
J2dRlsTraceLn(J2D_TRACE_INFO, "failed to get image");
}
else {
J2dRlsTraceLn(J2D_TRACE_INFO, "obtained image");
}
auto images = _swapchain_khr.getImages();
vk::CommandPoolCreateInfo poolInfo{
{vk::CommandPoolCreateFlagBits::eResetCommandBuffer},
static_cast<uint32_t>(device.queue_family())
};
auto pool = device.createCommandPool(poolInfo);
vk::CommandBufferAllocateInfo buffInfo{
*pool, vk::CommandBufferLevel::ePrimary, (uint32_t) 1, nullptr
};
auto buffers = device.allocateCommandBuffers(buffInfo);
vk::CommandBufferBeginInfo begInfo{
};
uint32_t alpha = (bg_color() >> 24) & 0xFF;
uint32_t red = (bg_color() >> 16) & 0xFF;
uint32_t green = (bg_color() >> 8) & 0xFF;
uint32_t blue = bg_color() & 0xFF;
vk::ClearColorValue color = {
static_cast<float>(red)/255.0f,
static_cast<float>(green)/255.0f,
static_cast<float>(blue)/255.0f,
static_cast<float>(alpha)/255.0f
};
std::vector<vk::ImageSubresourceRange> range = {{
vk::ImageAspectFlagBits::eColor,
0, 1, 0, 1}};
buffers[0].begin(begInfo);
buffers[0].clearColorImage(images[img.second], vk::ImageLayout::eSharedPresentKHR, color, range);
buffers[0].end();
vk::SubmitInfo submitInfo{
nullptr, nullptr, *buffers[0], nullptr
};
auto queue = device.getQueue(device.queue_family(), 0);
queue.submit(submitInfo, nullptr);
queue.waitIdle();
vk::PresentInfoKHR presentInfo;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &*_swapchain_khr;
presentInfo.pImageIndices = &(img.second);
queue.presentKHR(presentInfo);
queue.waitIdle();
device.waitIdle();
}

View File

@@ -27,45 +27,18 @@
#ifndef WLVKSurfaceData_h_Included
#define WLVKSurfaceData_h_Included
#include <cstdlib>
#include <vulkan/vulkan.h>
#include <SurfaceData.h>
#include <VKBase.h>
#include "VKSurfaceData.h"
#ifdef HEADLESS
#define WLVKSDOps void
#else /* HEADLESS */
#ifndef HEADLESS
class WLVKSurfaceData : public VKSurfaceData {
wl_surface* _wl_surface;
vk::raii::SurfaceKHR _surface_khr;
vk::raii::SwapchainKHR _swapchain_khr;
class WLVKSurfaceData : public VKSwapchainSurfaceData {
wl_surface* _wl_surface;
public:
WLVKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc);
WLVKSurfaceData(uint32_t w, uint32_t h, uint32_t s, uint32_t bgc)
: VKSwapchainSurfaceData(w, h, s, bgc), _wl_surface(nullptr) {}
void validate(wl_surface* wls);
void revalidate(uint32_t w, uint32_t h, uint32_t s);
void set_bg_color(uint32_t bgc);
void update();
};
/**
* The WLVKSDOps structure contains the WLVK-specific information for a given
* WLVKSurfaceData. It is referenced by the native OGLSDOps structure.
*
* wl_surface* wlSurface;
* For onscreen windows, we maintain a reference to that window's associated
* wl_surface handle here. Offscreen surfaces have no associated Window, so for
* those surfaces, this value will simply be zero.
*
* VkSurfaceKHR* surface;
* Vulkan surface associated with this surface.
*/
typedef struct _WLVKSDOps {
SurfaceDataOps sdOps;
WLVKSurfaceData* wlvkSD;
pthread_mutex_t lock;
} WLVKSDOps;
#endif /* HEADLESS */
#endif /* WLVKSurfaceData_h_Included */

View File

@@ -82,22 +82,9 @@ ReportFatalError(const char* file, int line, const char *msg)
assert(0);
}
static inline void
AssertCalledOnEDT(const char* file, int line)
{
char threadName[16];
pthread_getname_np(pthread_self(), threadName, sizeof(threadName));
if (strncmp(threadName, "AWT-EventQueue", 14) != 0) {
fprintf(stderr, "Assert failed (called on %s instead of EDT) at %s:%d\n", threadName, file, line);
fflush(stderr);
assert(0);
}
}
static void
AssertDrawLockIsHeld(WLSurfaceBufferManager* manager, const char * file, int line);
#define ASSERT_ON_EDT() AssertCalledOnEDT(__FILE__, __LINE__)
#define WL_FATAL_ERROR(msg) ReportFatalError(__FILE__, __LINE__, msg)
#define ASSERT_DRAW_LOCK_IS_HELD(manager) AssertDrawLockIsHeld(manager, __FILE__, __LINE__)
#define ASSERT_SHOW_LOCK_IS_HELD(manager) AssertShowLockIsHeld(manager, __FILE__, __LINE__)
@@ -770,7 +757,7 @@ WLSBM_Create(jint width, jint height, jint scale, jint bgPixel, jint wlShmFormat
// both read from and written to (when scrolling, for instance).
// So it needs to be able to be "locked" twice: once for writing and
// once for reading.
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&manager->drawLock, &attr);
DrawBufferCreate(manager);
ShowBufferCreate(manager);

View File

@@ -261,7 +261,7 @@ Java_sun_java2d_wl_WLSMSurfaceData_initOps(JNIEnv *env, jobject wsd,
// Recursive mutex is required because blit can be done with both source
// and destination being the same surface (during scrolling, for example).
// So WLSD_Lock() should be able to lock the same surface twice in a row.
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&wsdo->lock, &attr);
#endif /* !HEADLESS */
}

View File

@@ -280,8 +280,11 @@ JNI_OnUnload(JavaVM *vm, void *reserved) {
#define TEXT_AA_LCD_VRGB 6
#define TEXT_AA_LCD_VBGR 7
static void setRenderingFontHintsField(FcPattern* matchPattern, const char* property, int* value) {
if (FcResultMatch != (*fcPatternGetBool)(matchPattern, property, 0, value)) {
typedef FcResult (*FcPatternGetValueFuncType)(const FcPattern *p, const char *object, int n, void *b);
static void setRenderingFontHintsField(FcPatternGetValueFuncType fcPatternGetValue, FcPattern* matchPattern,
const char* property, int* value) {
if (FcResultMatch != (*fcPatternGetValue)(matchPattern, property, 0, value)) {
*value = -1;
}
}
@@ -292,10 +295,13 @@ JNIEXPORT int setupRenderingFontHints
FcPattern *pattern, *matchPattern;
FcResult result;
if (fcName == NULL) {
if (usingFontConfig() == false) {
return -1;
}
if (fcName == NULL) {
return -1;
}
pattern = (*fcNameParse)((FcChar8 *)fcName);
if (locale != NULL) {
(*fcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
@@ -312,13 +318,19 @@ JNIEXPORT int setupRenderingFontHints
*/
if (matchPattern) {
// Extract values from result
setRenderingFontHintsField(matchPattern, FC_HINTING, &renderingFontHints->fcHinting);
setRenderingFontHintsField(matchPattern, FC_HINT_STYLE, &renderingFontHints->fcHintStyle);
setRenderingFontHintsField(matchPattern, FC_ANTIALIAS, &renderingFontHints->fcAntialias);
setRenderingFontHintsField(matchPattern, FC_AUTOHINT, &renderingFontHints->fcAutohint);
setRenderingFontHintsField(matchPattern, FC_LCD_FILTER, &renderingFontHints->fcRGBA);
setRenderingFontHintsField(matchPattern, FC_RGBA, &renderingFontHints->fcLCDFilter);
setRenderingFontHintsField((FcPatternGetValueFuncType)(fcPatternGetBool), matchPattern, FC_HINTING,
&renderingFontHints->fcHinting);
setRenderingFontHintsField((FcPatternGetValueFuncType)(fcPatternGetInteger), matchPattern, FC_HINT_STYLE,
&renderingFontHints->fcHintStyle);
setRenderingFontHintsField((FcPatternGetValueFuncType)(fcPatternGetBool), matchPattern, FC_ANTIALIAS,
&renderingFontHints->fcAntialias);
setRenderingFontHintsField((FcPatternGetValueFuncType)(fcPatternGetBool), matchPattern, FC_AUTOHINT,
&renderingFontHints->fcAutohint);
setRenderingFontHintsField((FcPatternGetValueFuncType)(fcPatternGetInteger), matchPattern, FC_RGBA,
&renderingFontHints->fcRGBA);
setRenderingFontHintsField((FcPatternGetValueFuncType)(fcPatternGetInteger), matchPattern, FC_LCD_FILTER,
&renderingFontHints->fcLCDFilter);
(*fcPatternDestroy)(matchPattern);
}
(*fcPatternDestroy)(pattern);

View File

@@ -0,0 +1,138 @@
#ifndef JNIUTILITIES_H_
#define JNIUTILITIES_H_
#include "jni.h"
#include "jni_util.h"
#define CHECK_NULL_THROW_OOME(env, x, msg) \
do { \
if ((x) == NULL) { \
JNU_ThrowOutOfMemoryError((env), (msg));\
return; \
} \
} while(0) \
#define CHECK_NULL_THROW_OOME_RETURN(env, x, msg, z)\
do { \
if ((x) == NULL) { \
JNU_ThrowOutOfMemoryError((env), (msg));\
return (z); \
} \
} while(0) \
#define CHECK_NULL_THROW_IE(env, x, msg) \
do { \
if ((x) == NULL) { \
JNU_ThrowInternalError((env), (msg));\
return; \
} \
} while(0) \
/******** GET CLASS SUPPORT *********/
#define GET_CLASS(dst_var, cls) \
if (dst_var == NULL) { \
dst_var = (*env)->FindClass(env, cls); \
if (dst_var != NULL) dst_var = (*env)->NewGlobalRef(env, dst_var); \
} \
CHECK_NULL(dst_var);
#define DECLARE_CLASS(dst_var, cls) \
static jclass dst_var = NULL; \
GET_CLASS(dst_var, cls);
#define GET_CLASS_RETURN(dst_var, cls, ret) \
if (dst_var == NULL) { \
dst_var = (*env)->FindClass(env, cls); \
if (dst_var != NULL) dst_var = (*env)->NewGlobalRef(env, dst_var); \
} \
CHECK_NULL_RETURN(dst_var, ret);
#define DECLARE_CLASS_RETURN(dst_var, cls, ret) \
static jclass dst_var = NULL; \
GET_CLASS_RETURN(dst_var, cls, ret);
/******** GET METHOD SUPPORT *********/
#define GET_METHOD(dst_var, cls, name, signature) \
if (dst_var == NULL) { \
dst_var = (*env)->GetMethodID(env, cls, name, signature); \
} \
CHECK_NULL(dst_var);
#define DECLARE_METHOD(dst_var, cls, name, signature) \
static jmethodID dst_var = NULL; \
GET_METHOD(dst_var, cls, name, signature);
#define GET_METHOD_RETURN(dst_var, cls, name, signature, ret) \
if (dst_var == NULL) { \
dst_var = (*env)->GetMethodID(env, cls, name, signature); \
} \
CHECK_NULL_RETURN(dst_var, ret);
#define DECLARE_METHOD_RETURN(dst_var, cls, name, signature, ret) \
static jmethodID dst_var = NULL; \
GET_METHOD_RETURN(dst_var, cls, name, signature, ret);
#define GET_STATIC_METHOD(dst_var, cls, name, signature) \
if (dst_var == NULL) { \
dst_var = (*env)->GetStaticMethodID(env, cls, name, signature); \
} \
CHECK_NULL(dst_var);
#define DECLARE_STATIC_METHOD(dst_var, cls, name, signature) \
static jmethodID dst_var = NULL; \
GET_STATIC_METHOD(dst_var, cls, name, signature);
#define GET_STATIC_METHOD_RETURN(dst_var, cls, name, signature, ret) \
if (dst_var == NULL) { \
dst_var = (*env)->GetStaticMethodID(env, cls, name, signature); \
} \
CHECK_NULL_RETURN(dst_var, ret);
#define DECLARE_STATIC_METHOD_RETURN(dst_var, cls, name, signature, ret) \
static jmethodID dst_var = NULL; \
GET_STATIC_METHOD_RETURN(dst_var, cls, name, signature, ret);
/******** GET FIELD SUPPORT *********/
#define GET_FIELD(dst_var, cls, name, signature) \
if (dst_var == NULL) { \
dst_var = (*env)->GetFieldID(env, cls, name, signature); \
} \
CHECK_NULL(dst_var);
#define DECLARE_FIELD(dst_var, cls, name, signature) \
static jfieldID dst_var = NULL; \
GET_FIELD(dst_var, cls, name, signature);
#define GET_FIELD_RETURN(dst_var, cls, name, signature, ret) \
if (dst_var == NULL) { \
dst_var = (*env)->GetFieldID(env, cls, name, signature); \
} \
CHECK_NULL_RETURN(dst_var, ret);
#define DECLARE_FIELD_RETURN(dst_var, cls, name, signature, ret) \
static jfieldID dst_var = NULL; \
GET_FIELD_RETURN(dst_var, cls, name, signature, ret);
#define GET_STATIC_FIELD_RETURN(dst_var, cls, name, signature, ret) \
if (dst_var == NULL) { \
dst_var = (*env)->GetStaticFieldID(env, cls, name, signature); \
} \
CHECK_NULL_RETURN(dst_var, ret);
#define DECLARE_STATIC_FIELD_RETURN(dst_var, cls, name, signature, ret) \
static jfieldID dst_var = NULL; \
GET_STATIC_FIELD_RETURN(dst_var, cls, name, signature, ret);
/******** EXCEPTIONS SUPPORT *********/
#define EXCEPTION_CLEAR(env) \
if ((*env)->ExceptionCheck(env)) { \
(*env)->ExceptionClear(env); \
}
#endif // JNIUTILITIES_H_

View File

@@ -0,0 +1,677 @@
/*
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "JNIUtilities.h"
#include "sun_awt_wl_WLClipboard.h"
#include "wayland-client-protocol.h"
#include "WLToolkit.h"
// A type both zwp_primary_selection_source_v1* and wl_data_source*
// are convertible to.
typedef void* data_source_t;
static jmethodID transferContentsWithTypeMID; // WLCipboard.transferContentsWithType()
static jmethodID handleClipboardFormatMID; // WLCipboard.handleClipboardFormat()
static jmethodID handleNewClipboardMID; // WLCipboard.handleNewClipboard()
static jfieldID isPrimaryFID; // WLClipboard.isPrimary
typedef struct DataSourcePayload {
jobject clipboard; // a global reference to WLClipboard
jobject content; // a global reference to Transferable
} DataSourcePayload;
static DataSourcePayload *
DataSourcePayload_Create(jobject clipboard, jobject content)
{
DataSourcePayload * payload = malloc(sizeof(struct DataSourcePayload));
if (payload) {
payload->clipboard = clipboard;
payload->content = content;
}
return payload;
}
static void
DataSourcePayload_Destroy(DataSourcePayload* payload)
{
free(payload);
}
typedef struct DataOfferPayload {
jobject clipboard; // a global reference to WLClipboard
} DataOfferPayload;
static DataOfferPayload *
DataOfferPayload_Create(jobject clipboard)
{
// NB: this payload is associated with the clipboard and, once created,
// is never destroyed, much like the clipboard itself.
DataOfferPayload * payload = malloc(sizeof(struct DataOfferPayload));
if (payload) {
payload->clipboard = clipboard;
}
return payload;
}
// Clipboard "devices", one for the actual clipboard and one for the selection clipboard.
// Implicitly assumed that WLClipboard can only create once instance of each.
static struct wl_data_device *wl_data_device;
static struct zwp_primary_selection_device_v1 *zwp_selection_device;
static void data_device_handle_data_offer(
void *data,
struct wl_data_device *data_device,
struct wl_data_offer *offer);
static void data_device_handle_selection(
void *data,
struct wl_data_device *data_device,
struct wl_data_offer *offer);
static void
data_device_handle_enter(
void *data,
struct wl_data_device *wl_data_device,
uint32_t serial,
struct wl_surface *surface,
wl_fixed_t x,
wl_fixed_t y,
struct wl_data_offer *id)
{
// TODO
}
static void
data_device_handle_leave(void *data, struct wl_data_device *wl_data_device)
{
// TODO
}
static void
data_device_handle_motion(
void *data,
struct wl_data_device *wl_data_device,
uint32_t time,
wl_fixed_t x,
wl_fixed_t y)
{
// TODO
}
static void
data_device_handle_drop(void *data, struct wl_data_device *wl_data_device)
{
// TODO
}
static const struct wl_data_device_listener wl_data_device_listener = {
.data_offer = data_device_handle_data_offer,
.selection = data_device_handle_selection,
.enter = data_device_handle_enter,
.leave = data_device_handle_leave,
.motion = data_device_handle_motion
};
static void
RegisterDataOfferWithMimeType(DataOfferPayload *payload, void *offer, const char *mime_type)
{
JNIEnv *env = getEnv();
jstring mimeTypeString = (*env)->NewStringUTF(env, mime_type);
EXCEPTION_CLEAR(env);
if (mimeTypeString) {
(*env)->CallVoidMethod(env, payload->clipboard, handleClipboardFormatMID, ptr_to_jlong(offer), mimeTypeString);
EXCEPTION_CLEAR(env);
(*env)->DeleteLocalRef(env, mimeTypeString);
}
}
static void
RegisterDataOffer(DataOfferPayload *payload, void *offer)
{
JNIEnv *env = getEnv();
(*env)->CallVoidMethod(env, payload->clipboard, handleNewClipboardMID, ptr_to_jlong(offer));
EXCEPTION_CLEAR(env);
}
static void
zwp_selection_offer(
void *data,
struct zwp_primary_selection_offer_v1 *offer,
const char *mime_type)
{
assert (data != NULL);
RegisterDataOfferWithMimeType(data, offer, mime_type);
}
const struct zwp_primary_selection_offer_v1_listener zwp_selection_offer_listener = {
.offer = zwp_selection_offer
};
static void
zwp_selection_device_handle_data_offer(
void *data,
struct zwp_primary_selection_device_v1 *device,
struct zwp_primary_selection_offer_v1 *offer)
{
zwp_primary_selection_offer_v1_add_listener(offer, &zwp_selection_offer_listener, data);
}
static void
zwp_selection_device_handle_selection(
void *data,
struct zwp_primary_selection_device_v1 *device,
struct zwp_primary_selection_offer_v1 *offer)
{
assert (data != NULL);
RegisterDataOffer(data, offer);
}
static const struct zwp_primary_selection_device_v1_listener zwp_selection_device_listener = {
.data_offer = zwp_selection_device_handle_data_offer,
.selection = zwp_selection_device_handle_selection
};
static void
wl_action(void *data, struct wl_data_offer *wl_data_offer, uint32_t dnd_action)
{
// TODO: this is for DnD
}
static void
wl_offer(void *data, struct wl_data_offer *offer, const char *mime_type)
{
assert (data != NULL);
RegisterDataOfferWithMimeType(data, offer, mime_type);
}
static void
wl_source_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions)
{
// TODO: this is for DnD
}
static const struct wl_data_offer_listener wl_data_offer_listener = {
.action = wl_action,
.offer = wl_offer,
.source_actions = wl_source_actions
};
static void
data_device_handle_data_offer(
void *data,
struct wl_data_device *data_device,
struct wl_data_offer *offer)
{
wl_data_offer_add_listener(offer, &wl_data_offer_listener, data);
}
static void data_device_handle_selection(
void *data,
struct wl_data_device *data_device,
struct wl_data_offer *offer)
{
assert (data != NULL);
RegisterDataOffer(data, offer);
}
static void
SendClipboardToFD(DataSourcePayload *payload, const char *mime_type, int fd)
{
JNIEnv *env = getEnv();
jstring mime_type_string = (*env)->NewStringUTF(env, mime_type);
EXCEPTION_CLEAR(env);
if (payload->clipboard != NULL && payload->content != NULL && mime_type_string != NULL && fd >= 0) {
(*env)->CallVoidMethod(env,
payload->clipboard,
transferContentsWithTypeMID,
payload->content,
mime_type_string,
fd);
EXCEPTION_CLEAR(env);
} else {
// The file is normally closed on the Java side, so only close here
// if the Java side wasn't involved.
close(fd);
}
if (mime_type_string != NULL) {
(*env)->DeleteLocalRef(env, mime_type_string);
}
}
static void
CleanupClipboard(DataSourcePayload *payload)
{
if (payload != NULL) {
JNIEnv* env = getEnv();
if (payload->clipboard != NULL) (*env)->DeleteGlobalRef(env, payload->clipboard);
if (payload->content != NULL) (*env)->DeleteGlobalRef(env, payload->content);
DataSourcePayload_Destroy(payload);
}
}
static void
wl_data_source_target(void *data,
struct wl_data_source *wl_data_source,
const char *mime_type)
{
// TODO
}
static void
wl_data_source_handle_send(
void *data,
struct wl_data_source *source,
const char *mime_type,
int fd)
{
assert(data);
SendClipboardToFD(data, mime_type, fd);
}
static void
wl_data_source_handle_cancelled(
void *data,
struct wl_data_source *source)
{
CleanupClipboard(data);
wl_data_source_destroy(source);
}
static const struct wl_data_source_listener wl_data_source_listener = {
.target = wl_data_source_target,
.send = wl_data_source_handle_send,
.cancelled = wl_data_source_handle_cancelled
};
static void
zwp_selection_source_handle_send(
void *data,
struct zwp_primary_selection_source_v1 *source,
const char *mime_type,
int32_t fd)
{
DataSourcePayload * payload = data;
assert(payload);
SendClipboardToFD(payload, mime_type, fd);
}
static void
zwp_selection_source_handle_cancelled(
void *data,
struct zwp_primary_selection_source_v1 *source)
{
CleanupClipboard(data);
zwp_primary_selection_source_v1_destroy(source);
}
static const struct zwp_primary_selection_source_v1_listener zwp_selection_source_listener = {
.send = zwp_selection_source_handle_send,
.cancelled = zwp_selection_source_handle_cancelled
};
static jboolean
initJavaRefs(JNIEnv* env, jclass wlClipboardClass)
{
GET_METHOD_RETURN(transferContentsWithTypeMID,
wlClipboardClass,
"transferContentsWithType",
"(Ljava/awt/datatransfer/Transferable;Ljava/lang/String;I)V",
JNI_FALSE);
GET_METHOD_RETURN(handleClipboardFormatMID,
wlClipboardClass,
"handleClipboardFormat",
"(JLjava/lang/String;)V",
JNI_FALSE);
GET_METHOD_RETURN(handleNewClipboardMID,
wlClipboardClass,
"handleNewClipboard",
"(J)V",
JNI_FALSE);
GET_FIELD_RETURN(isPrimaryFID,
wlClipboardClass,
"isPrimary",
"Z",
JNI_FALSE);
return JNI_TRUE;
}
/**
* Returns JNI_TRUE if the WLClipboard referred to by wlClipboard
* corresponds to the "primary selection" clipboard and JNI_FALSE
* otherwise.
* Depending on that, a different protocol must be used to communicate
* with Wayland (zwp_primary_selection_device_manager_v1 and
* wl_data_device_manager correspondingly).
*/
static jboolean
isPrimarySelectionClipboard(JNIEnv* env, jobject wlClipboard)
{
return (*env)->GetBooleanField(env, wlClipboard, isPrimaryFID);
}
/**
* Initializes data common to all clipboard objects. Called once in
* static initialization time of the WLClipboard class.
*
* Throws InternalError in case of any errors.
*/
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLClipboard_initIDs(
JNIEnv *env,
jclass wlClipboardClass)
{
if (!initJavaRefs(env, wlClipboardClass)) {
JNU_ThrowInternalError(env, "Failed to find WLClipboard members");
}
}
JNIEXPORT jlong JNICALL
Java_sun_awt_wl_WLClipboard_createDataOfferQueue(
JNIEnv *env,
jclass wlClipboardClass)
{
struct wl_event_queue * queue = wl_display_create_queue(wl_display);
if (queue == NULL) {
JNU_ThrowInternalError(env, "Couldn't create an event queue for the clipboard");
}
return ptr_to_jlong(queue);
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLClipboard_dispatchDataOfferQueueImpl(
JNIEnv *env,
jclass wlClipboardClass,
jlong dataOfferQueuePtr)
{
struct wl_event_queue * queue = jlong_to_ptr(dataOfferQueuePtr);
assert (queue != NULL);
while (wl_display_dispatch_queue(wl_display, queue) != -1) {
}
}
/**
* Initializes data for a specific clipboard object (the primary selection
* or the regular one). Called once per clipboard type.
*
* Returns the native handle to the corresponding clipboard.
*
* Throws UnsupportedOperationException in case of the primary selection
* clipboard is not available and isPrimary is true.
* Throws IllegalStateException in case of double-initialization.
*/
JNIEXPORT jlong JNICALL
Java_sun_awt_wl_WLClipboard_initNative(
JNIEnv *env,
jobject obj,
jboolean isPrimary)
{
if (!isPrimary) {
if (wl_data_device != NULL) {
JNU_ThrowByName(env, "java/lang/IllegalStateException", "one data device has already been created");
return 0;
}
} else {
if (zwp_selection_device != NULL) {
JNU_ThrowByName(env,
"java/lang/IllegalStateException",
"one primary selection device has already been created");
return 0;
}
}
jobject clipboardGlobalRef = (*env)->NewGlobalRef(env, obj); // normally never deleted
CHECK_NULL_RETURN(clipboardGlobalRef, 0);
DataOfferPayload *payload = DataOfferPayload_Create(clipboardGlobalRef);
if (payload == NULL) {
(*env)->DeleteGlobalRef(env, clipboardGlobalRef);
}
CHECK_NULL_THROW_OOME_RETURN(env, payload, "failed to allocate memory for DataOfferPayload", 0);
if (!isPrimary) {
// TODO: may be needed by DnD also, initialize in a common place
wl_data_device = wl_data_device_manager_get_data_device(wl_ddm, wl_seat);
wl_data_device_add_listener(wl_data_device, &wl_data_device_listener, payload);
} else {
if (zwp_selection_dm != NULL) {
zwp_selection_device = zwp_primary_selection_device_manager_v1_get_device(zwp_selection_dm, wl_seat);
zwp_primary_selection_device_v1_add_listener(zwp_selection_device, &zwp_selection_device_listener, payload);
} else {
(*env)->DeleteGlobalRef(env, clipboardGlobalRef);
JNU_ThrowByName(env,
"java/lang/UnsupportedOperationException",
"zwp_primary_selection_device_manager_v1 not available");
}
}
return ptr_to_jlong(wl_data_device);
}
static jboolean
announceMimeTypesForSource(
JNIEnv * env,
jboolean isPrimary,
jobjectArray mimeTypes,
data_source_t source)
{
jint length = (*env)->GetArrayLength(env, mimeTypes);
for (jint i = 0; i < length; i++) {
jstring s = (*env)->GetObjectArrayElement(env, mimeTypes, i);
JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
const char *mimeType = (*env)->GetStringUTFChars(env, s, JNI_FALSE);
CHECK_NULL_RETURN(mimeType, JNI_FALSE);
if (isPrimary) {
zwp_primary_selection_source_v1_offer((struct zwp_primary_selection_source_v1 *)source, mimeType);
} else {
wl_data_source_offer((struct wl_data_source *)source, mimeType);
}
(*env)->ReleaseStringUTFChars(env, s, mimeType);
(*env)->DeleteLocalRef(env, s);
}
return JNI_TRUE;
}
static jboolean
offerData(
JNIEnv* env,
DataSourcePayload * payload,
jboolean isPrimary,
jlong eventSerial,
jobjectArray mimeTypes,
jlong dataOfferQueuePtr)
{
data_source_t source = isPrimary
? (data_source_t)zwp_primary_selection_device_manager_v1_create_source(zwp_selection_dm)
: (data_source_t)wl_data_device_manager_create_data_source(wl_ddm);
if (source != NULL) {
wl_proxy_set_queue((struct wl_proxy*)source, jlong_to_ptr(dataOfferQueuePtr));
if (isPrimary) {
zwp_primary_selection_source_v1_add_listener(
(struct zwp_primary_selection_source_v1 *)source,
&zwp_selection_source_listener,
payload);
} else {
wl_data_source_add_listener(
(struct wl_data_source *)source,
&wl_data_source_listener,
payload);
}
if (mimeTypes != NULL) {
if (!announceMimeTypesForSource(env, isPrimary, mimeTypes, source)) {
if (isPrimary) {
zwp_primary_selection_source_v1_destroy(source);
} else {
wl_data_source_destroy(source);
}
return JNI_FALSE;
}
}
if (isPrimary) {
zwp_primary_selection_device_v1_set_selection(
zwp_selection_device,
(struct zwp_primary_selection_source_v1 *)source,
eventSerial);
}
else {
wl_data_device_set_selection(
wl_data_device,
(struct wl_data_source *)source,
eventSerial);
}
}
return source != NULL;
}
/**
* Makes Wayland aware of the availability of new clipboard content in the
* given MIME formats.
* Retains the reference to clipboard content for the further use when the actual
* clipboard data get requested.
*/
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLClipboard_offerData(
JNIEnv *env,
jobject obj,
jlong eventSerial,
jobjectArray mimeTypes,
jobject content,
jlong dataOfferQueuePtr)
{
jobject clipboardGlobalRef = (*env)->NewGlobalRef(env, obj); // deleted by ...source_handle_cancelled()
CHECK_NULL(clipboardGlobalRef);
jobject contentGlobalRef = (*env)->NewGlobalRef(env, content); // deleted by ...source_handle_cancelled()
CHECK_NULL(contentGlobalRef);
DataSourcePayload * payload = DataSourcePayload_Create(clipboardGlobalRef, contentGlobalRef);
if (payload == NULL) {
(*env)->DeleteGlobalRef(env, clipboardGlobalRef);
(*env)->DeleteGlobalRef(env, contentGlobalRef);
}
CHECK_NULL_THROW_OOME(env, payload, "failed to allocate memory for DataSourcePayload");
const jboolean isPrimary = isPrimarySelectionClipboard(env, obj);
if (!offerData(env,payload, isPrimary, eventSerial, mimeTypes, dataOfferQueuePtr)) {
// Failed to create a data source; give up and cleanup.
CleanupClipboard(payload);
}
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLClipboard_cancelOffer(
JNIEnv *env,
jobject obj,
jlong eventSerial)
{
// This should automatically deliver the "cancelled" event where we clean up
// both the previous source and the global reference to the transferable object.
const jboolean isPrimary = isPrimarySelectionClipboard(env, obj);
if (isPrimary) {
zwp_primary_selection_device_v1_set_selection(zwp_selection_device, NULL, eventSerial);
} else {
wl_data_device_set_selection(wl_data_device, NULL, eventSerial);
}
}
/**
* Asks Wayland to provide the data for the clipboard in the given MIME
* format.
*
* Returns the file desriptor from which the data must be read or -1
* in case of an error.
*
* NB: the returned file descriptor must be closed by the caller.
*/
JNIEXPORT jint JNICALL
Java_sun_awt_wl_WLClipboard_requestDataInFormat(
JNIEnv *env,
jobject obj,
jlong clipboardNativePtr,
jstring mimeTypeJava)
{
assert (clipboardNativePtr != 0);
const jboolean isPrimary = isPrimarySelectionClipboard(env, obj);
int fd = -1; // The file descriptor the clipboard data will be read from by Java
const char * mimeType = (*env)->GetStringUTFChars(env, mimeTypeJava, NULL);
if (mimeType) {
int fds[2];
int rc = pipe(fds);
if (rc == 0) {
if (isPrimary) {
struct zwp_primary_selection_offer_v1 * offer = jlong_to_ptr(clipboardNativePtr);
zwp_primary_selection_offer_v1_receive(offer, mimeType, fds[1]);
} else {
struct wl_data_offer * offer = jlong_to_ptr(clipboardNativePtr);
wl_data_offer_receive(offer, mimeType, fds[1]);
}
close(fds[1]); // close the "sender" end of the pipe
fd = fds[0];
}
(*env)->ReleaseStringUTFChars(env, mimeTypeJava, mimeType);
}
return fd;
}
/**
* Destroys the corresponding Wayland proxy objects pointed to by clipboardNativePtr.
*/
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLClipboard_destroyClipboard(
JNIEnv *env,
jobject obj,
jlong clipboardNativePtr)
{
assert(clipboardNativePtr != 0);
if (isPrimarySelectionClipboard(env, obj)) {
struct zwp_primary_selection_offer_v1 * offer = jlong_to_ptr(clipboardNativePtr);
zwp_primary_selection_offer_v1_destroy(offer);
} else {
struct wl_data_offer * offer = jlong_to_ptr(clipboardNativePtr);
wl_data_offer_destroy(offer);
}
}

View File

@@ -28,8 +28,9 @@
#include <jni.h>
#include <Trace.h>
#include <assert.h>
#include <gtk-shell1-client-protocol.h>
#include "jni_util.h"
#include "JNIUtilities.h"
#include "WLToolkit.h"
#include "WLRobotPeer.h"
#include "WLGraphicsEnvironment.h"
@@ -44,12 +45,54 @@ static jmethodID notifyConfiguredMID;
static jmethodID notifyEnteredOutputMID;
static jmethodID notifyLeftOutputMID;
struct activation_token_list_item {
struct xdg_activation_token_v1 *token;
struct activation_token_list_item *next_item;
};
static struct activation_token_list_item *add_token(struct activation_token_list_item *list,
struct xdg_activation_token_v1 *token_to_add) {
struct activation_token_list_item *new_item =
(struct activation_token_list_item *) calloc(1, sizeof(struct activation_token_list_item));
new_item->token = token_to_add;
new_item->next_item = list;
return new_item;
}
static struct activation_token_list_item *delete_last_token(struct activation_token_list_item *list) {
assert(list);
xdg_activation_token_v1_destroy(list->token);
struct activation_token_list_item *next_item = list->next_item;
free(list);
return next_item;
}
static struct activation_token_list_item *delete_token(struct activation_token_list_item *list,
struct xdg_activation_token_v1 *token_to_delete) {
if (list == NULL) {
return NULL;
} else if (list->token == token_to_delete) {
return delete_last_token(list);
} else {
list->next_item = delete_token(list->next_item, token_to_delete);
return list;
}
}
static void delete_all_tokens(struct activation_token_list_item *list) {
while (list) {
list = delete_last_token(list);
}
}
struct WLFrame {
jobject nativeFramePeer; // weak reference
struct wl_surface *wl_surface;
struct xdg_surface *xdg_surface;
struct gtk_surface1 *gtk_surface;
struct WLFrame *parent;
struct xdg_positioner *xdg_positioner;
struct activation_token_list_item *activation_token_list;
jboolean toplevel;
union {
struct xdg_toplevel *xdg_toplevel;
@@ -224,6 +267,22 @@ static const struct xdg_popup_listener xdg_popup_listener = {
.popup_done = xdg_popup_done,
};
static void
xdg_activation_token_v1_done(void *data,
struct xdg_activation_token_v1 *xdg_activation_token_v1,
const char *token) {
struct WLFrame *frame = (struct WLFrame *) data;
assert(frame);
struct wl_surface *surface = frame->wl_surface;
assert(surface);
xdg_activation_v1_activate(xdg_activation_v1, token, surface);
frame->activation_token_list = delete_token(frame->activation_token_list, xdg_activation_token_v1);
}
static const struct xdg_activation_token_v1_listener xdg_activation_token_v1_listener = {
.done = xdg_activation_token_v1_done,
};
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLComponentPeer_initIDs
(JNIEnv *env, jclass clazz)
@@ -352,7 +411,7 @@ Java_sun_awt_wl_WLComponentPeer_nativeRequestUnsetFullScreen
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLComponentPeer_nativeCreateWLSurface
(JNIEnv *env, jobject obj, jlong ptr, jlong parentPtr,
jint x, jint y,
jint x, jint y, jboolean isModal,
jstring title, jstring appid)
{
struct WLFrame *frame = (struct WLFrame *) ptr;
@@ -360,6 +419,9 @@ Java_sun_awt_wl_WLComponentPeer_nativeCreateWLSurface
if (frame->wl_surface) return;
frame->wl_surface = wl_compositor_create_surface(wl_compositor);
frame->xdg_surface = xdg_wm_base_get_xdg_surface(xdg_wm_base, frame->wl_surface);
if (gtk_shell1 != NULL) {
frame->gtk_surface = gtk_shell1_get_gtk_surface(gtk_shell1, frame->wl_surface);
}
wl_surface_add_listener(frame->wl_surface, &wl_surface_listener, frame);
xdg_surface_add_listener(frame->xdg_surface, &xdg_surface_listener, frame);
@@ -376,6 +438,10 @@ Java_sun_awt_wl_WLComponentPeer_nativeCreateWLSurface
xdg_toplevel_set_parent(frame->xdg_toplevel, parentFrame->xdg_toplevel);
}
if (isModal && frame->gtk_surface != NULL) {
gtk_surface1_set_modal(frame->gtk_surface);
}
#ifdef WAKEFIELD_ROBOT
if (wakefield) {
// TODO: this doesn't work quite as expected for some reason
@@ -438,8 +504,16 @@ DoHide(struct WLFrame *frame)
} else {
xdg_popup_destroy(frame->xdg_popup);
}
if (wl_surface_in_focus == frame->wl_surface) {
wl_surface_in_focus = NULL;
}
if (frame->gtk_surface != NULL) {
gtk_surface1_destroy(frame->gtk_surface);
}
xdg_surface_destroy(frame->xdg_surface);
wl_surface_destroy(frame->wl_surface);
delete_all_tokens(frame->activation_token_list);
frame->activation_token_list = NULL;
frame->wl_surface = NULL;
frame->xdg_surface = NULL;
frame->xdg_toplevel = NULL;
@@ -525,3 +599,20 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_WLComponentPeer_nativeShowWindowMenu
xdg_toplevel_show_window_menu(frame->xdg_toplevel, wl_seat, last_mouse_pressed_serial, x, y);
}
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLComponentPeer_nativeActivate
(JNIEnv *env, jobject obj, jlong ptr)
{
struct WLFrame *frame = jlong_to_ptr(ptr);
if (frame->wl_surface && xdg_activation_v1 && wl_seat) {
struct xdg_activation_token_v1 *token = xdg_activation_v1_get_activation_token(xdg_activation_v1);
xdg_activation_token_v1_add_listener(token, &xdg_activation_token_v1_listener, frame);
xdg_activation_token_v1_set_serial(token, last_input_or_focus_serial, wl_seat);
if (wl_surface_in_focus) {
xdg_activation_token_v1_set_surface(token, wl_surface_in_focus);
}
xdg_activation_token_v1_commit(token);
frame->activation_token_list = add_token(frame->activation_token_list, token);
}
}

View File

@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <Trace.h>
#include "jni_util.h"
#include "JNIUtilities.h"
#include "WLToolkit.h"
#include "VKBase.h"
@@ -43,11 +43,15 @@ typedef struct WLOutput {
int32_t y;
int32_t width;
int32_t height;
int32_t width_mm;
int32_t height_mm;
uint32_t subpixel;
uint32_t transform;
uint32_t scale;
char * make;
char * model;
char * name;
} WLOutput;
@@ -79,6 +83,10 @@ wl_output_geometry(
output->y = y;
output->subpixel = subpixel;
output->transform = transform;
output->width_mm = physical_width;
output->height_mm = physical_height;
output->make = make != NULL ? strdup(make) : NULL;
output->model = model != NULL ? strdup(model) : NULL;
}
static void
@@ -138,16 +146,23 @@ wl_output_done(
JNIEnv *env = getEnv();
jobject obj = (*env)->CallStaticObjectMethod(env, geClass, getSingleInstanceMID);
JNU_CHECK_EXCEPTION(env);
CHECK_NULL_THROW_IE(env, obj, "WLGraphicsEnvironment.getSingleInstance() returned null");
jstring outputName = output->name ? JNU_NewStringPlatform(env, output->name) : NULL;
jstring name = output->name ? JNU_NewStringPlatform(env, output->name) : NULL;
jstring make = output->make ? JNU_NewStringPlatform(env, output->make) : NULL;
jstring model = output->model ? JNU_NewStringPlatform(env, output->model) : NULL;
JNU_CHECK_EXCEPTION(env);
(*env)->CallVoidMethod(env, obj, notifyOutputConfiguredMID,
outputName,
name,
make,
model,
output->id,
output->x,
output->y,
output->width,
output->height,
output->width_mm,
output->height_mm,
(jint)output->subpixel,
(jint)output->transform,
(jint)output->scale);
@@ -182,7 +197,7 @@ WLGraphicsEnvironment_initIDs
CHECK_NULL_RETURN(
notifyOutputConfiguredMID = (*env)->GetMethodID(env, clazz,
"notifyOutputConfigured",
"(Ljava/lang/String;IIIIIIII)V"),
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIIIIII)V"),
JNI_FALSE);
CHECK_NULL_RETURN(
notifyOutputDestroyedMID = (*env)->GetMethodID(env, clazz,
@@ -221,6 +236,8 @@ WLOutputDeregister(struct wl_registry *wl_registry, uint32_t id)
wl_output_destroy(cur->wl_output);
WLOutput * next = cur->next;
free(cur->name);
free(cur->make);
free(cur->model);
free(cur);
cur = next;
} else {
@@ -266,7 +283,7 @@ WLOutputByID(uint32_t id)
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL
Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge)
Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge, jboolean verbose, jint requestedDevice)
{
jboolean vkwlAvailable = JNI_FALSE;
/* TODO: The following sequence lead to uninitialized awt lock
@@ -278,7 +295,7 @@ Java_sun_awt_wl_WLGraphicsEnvironment_initVKWL(JNIEnv *env, jclass wlge)
WLGraphicsEnvironment.initVKWL()
*/
//AWT_LOCK();
vkwlAvailable = VK_Init();
vkwlAvailable = VK_Init(verbose, requestedDevice);
//AWT_UNLOCK();
return vkwlAvailable;
}

View File

@@ -39,8 +39,10 @@
#include <unistd.h>
#include <time.h>
#include "gtk-shell1-client-protocol.h"
#include "jvm_md.h"
#include "jni_util.h"
#include "JNIUtilities.h"
#include "awt.h"
#include "sun_awt_wl_WLToolkit.h"
#include "WLToolkit.h"
@@ -58,6 +60,8 @@ struct wl_display *wl_display = NULL;
struct wl_shm *wl_shm = NULL;
struct wl_compositor *wl_compositor = NULL;
struct xdg_wm_base *xdg_wm_base = NULL;
struct xdg_activation_v1 *xdg_activation_v1 = NULL;
struct gtk_shell1* gtk_shell1 = NULL;
struct wl_seat *wl_seat = NULL;
struct wl_keyboard *wl_keyboard;
@@ -65,8 +69,13 @@ struct wl_pointer *wl_pointer;
struct wl_cursor_theme *wl_cursor_theme = NULL;
struct wl_surface *wl_surface_in_focus = NULL;
struct wl_data_device_manager *wl_ddm = NULL;
struct zwp_primary_selection_device_manager_v1 *zwp_selection_dm = NULL;
uint32_t last_mouse_pressed_serial = 0;
uint32_t last_pointer_enter_serial = 0;
uint32_t last_input_or_focus_serial = 0;
static uint32_t num_of_outstanding_sync = 0;
@@ -311,6 +320,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
pointer_event.button = button,
pointer_event.state = state;
if (state) {
last_input_or_focus_serial = serial;
last_mouse_pressed_serial = serial;
}
}
@@ -452,6 +462,9 @@ static void
wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
{
wl_surface_in_focus = surface;
last_input_or_focus_serial = serial;
JNIEnv* env = getEnv();
(*env)->CallStaticVoidMethod(env,
tkClass,
@@ -481,6 +494,8 @@ static void
wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, uint32_t time, uint32_t evdev_key, uint32_t state)
{
last_input_or_focus_serial = serial;
const uint32_t scancode = evdev_key + 8;
const uint32_t keychar32 = xkb_ifs.xkb_state_key_get_utf32(xkb_state, scancode);
const xkb_keysym_t keysym = xkb_ifs.xkb_state_key_get_one_sym(xkb_state, scancode);
@@ -503,6 +518,8 @@ static void
wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard,
uint32_t serial, struct wl_surface *surface)
{
wl_surface_in_focus = NULL;
JNIEnv* env = getEnv();
(*env)->CallStaticVoidMethod(env,
tkClass,
@@ -518,6 +535,8 @@ wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
uint32_t mods_latched, uint32_t mods_locked,
uint32_t group)
{
last_input_or_focus_serial = serial;
xkb_ifs.xkb_state_update_mask(xkb_state,
mods_depressed,
mods_latched,
@@ -668,7 +687,16 @@ registry_global(void *data, struct wl_registry *wl_registry,
} else if (strcmp(interface, wl_output_interface.name) == 0) {
WLOutputRegister(wl_registry, name);
process_new_listener_before_end_of_init();
} else if (strcmp(interface, xdg_activation_v1_interface.name) == 0) {
xdg_activation_v1 = wl_registry_bind(wl_registry, name, &xdg_activation_v1_interface, 1);
} else if (strcmp(interface, gtk_shell1_interface.name) == 0) {
gtk_shell1 = wl_registry_bind(wl_registry, name, &gtk_shell1_interface, 1);
} else if (strcmp(interface, wl_data_device_manager_interface.name) == 0) {
wl_ddm = wl_registry_bind(wl_registry, name,&wl_data_device_manager_interface, 3);
} else if (strcmp(interface, zwp_primary_selection_device_manager_v1_interface.name) == 0) {
zwp_selection_dm = wl_registry_bind(wl_registry, name,&zwp_primary_selection_device_manager_v1_interface, 1);
}
#ifdef WAKEFIELD_ROBOT
else if (strcmp(interface, wakefield_interface.name) == 0) {
wakefield = wl_registry_bind(wl_registry, name, &wakefield_interface, 1);

View File

@@ -26,6 +26,8 @@
#include <wayland-client.h>
#include <wayland-cursor.h>
#include "xdg-shell-client-protocol.h"
#include "xdg-activation-v1-client-protocol.h"
#include "primary-selection-client-protocol.h"
#define CHECK_NULL_THROW_OOME_RETURN(env, x, msg, z)\
do { \
@@ -43,15 +45,25 @@
} \
} while(0) \
struct gtk_shell1;
extern struct wl_seat *wl_seat;
extern struct wl_display *wl_display;
extern struct wl_pointer *wl_pointer;
extern struct wl_compositor *wl_compositor;
extern struct xdg_wm_base *xdg_wm_base;
extern struct xdg_activation_v1 *xdg_activation_v1;
extern struct gtk_shell1* gtk_shell1; // optional, check for NULL before use
extern struct wl_cursor_theme *wl_cursor_theme;
extern struct wl_data_device_manager *wl_ddm;
extern struct zwp_primary_selection_device_manager_v1 *zwp_selection_dm;
extern struct wl_surface *wl_surface_in_focus;
extern uint32_t last_mouse_pressed_serial;
extern uint32_t last_pointer_enter_serial;
extern uint32_t last_input_or_focus_serial;
JNIEnv *getEnv();

View File

@@ -0,0 +1,430 @@
/* Generated by wayland-scanner 1.19.0 */
#ifndef GTK_CLIENT_PROTOCOL_H
#define GTK_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_gtk The gtk protocol
* @section page_ifaces_gtk Interfaces
* - @subpage page_iface_gtk_shell1 - gtk specific extensions
* - @subpage page_iface_gtk_surface1 -
*/
struct gtk_shell1;
struct gtk_surface1;
struct wl_seat;
struct wl_surface;
#ifndef GTK_SHELL1_INTERFACE
#define GTK_SHELL1_INTERFACE
/**
* @page page_iface_gtk_shell1 gtk_shell1
* @section page_iface_gtk_shell1_desc Description
*
* gtk_shell is a protocol extension providing additional features for
* clients implementing it.
* @section page_iface_gtk_shell1_api API
* See @ref iface_gtk_shell1.
*/
/**
* @defgroup iface_gtk_shell1 The gtk_shell1 interface
*
* gtk_shell is a protocol extension providing additional features for
* clients implementing it.
*/
extern const struct wl_interface gtk_shell1_interface;
#endif
#ifndef GTK_SURFACE1_INTERFACE
#define GTK_SURFACE1_INTERFACE
/**
* @page page_iface_gtk_surface1 gtk_surface1
* @section page_iface_gtk_surface1_api API
* See @ref iface_gtk_surface1.
*/
/**
* @defgroup iface_gtk_surface1 The gtk_surface1 interface
*/
extern const struct wl_interface gtk_surface1_interface;
#endif
#ifndef GTK_SHELL1_CAPABILITY_ENUM
#define GTK_SHELL1_CAPABILITY_ENUM
enum gtk_shell1_capability {
GTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU = 1,
GTK_SHELL1_CAPABILITY_GLOBAL_MENU_BAR = 2,
GTK_SHELL1_CAPABILITY_DESKTOP_ICONS = 3,
};
#endif /* GTK_SHELL1_CAPABILITY_ENUM */
/**
* @ingroup iface_gtk_shell1
* @struct gtk_shell1_listener
*/
struct gtk_shell1_listener {
/**
*/
void (*capabilities)(void *data,
struct gtk_shell1 *gtk_shell1,
uint32_t capabilities);
};
/**
* @ingroup iface_gtk_shell1
*/
static inline int
gtk_shell1_add_listener(struct gtk_shell1 *gtk_shell1,
const struct gtk_shell1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) gtk_shell1,
(void (**)(void)) listener, data);
}
#define GTK_SHELL1_GET_GTK_SURFACE 0
#define GTK_SHELL1_SET_STARTUP_ID 1
#define GTK_SHELL1_SYSTEM_BELL 2
#define GTK_SHELL1_NOTIFY_LAUNCH 3
/**
* @ingroup iface_gtk_shell1
*/
#define GTK_SHELL1_CAPABILITIES_SINCE_VERSION 1
/**
* @ingroup iface_gtk_shell1
*/
#define GTK_SHELL1_GET_GTK_SURFACE_SINCE_VERSION 1
/**
* @ingroup iface_gtk_shell1
*/
#define GTK_SHELL1_SET_STARTUP_ID_SINCE_VERSION 1
/**
* @ingroup iface_gtk_shell1
*/
#define GTK_SHELL1_SYSTEM_BELL_SINCE_VERSION 1
/**
* @ingroup iface_gtk_shell1
*/
#define GTK_SHELL1_NOTIFY_LAUNCH_SINCE_VERSION 3
/** @ingroup iface_gtk_shell1 */
static inline void
gtk_shell1_set_user_data(struct gtk_shell1 *gtk_shell1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) gtk_shell1, user_data);
}
/** @ingroup iface_gtk_shell1 */
static inline void *
gtk_shell1_get_user_data(struct gtk_shell1 *gtk_shell1)
{
return wl_proxy_get_user_data((struct wl_proxy *) gtk_shell1);
}
static inline uint32_t
gtk_shell1_get_version(struct gtk_shell1 *gtk_shell1)
{
return wl_proxy_get_version((struct wl_proxy *) gtk_shell1);
}
/** @ingroup iface_gtk_shell1 */
static inline void
gtk_shell1_destroy(struct gtk_shell1 *gtk_shell1)
{
wl_proxy_destroy((struct wl_proxy *) gtk_shell1);
}
/**
* @ingroup iface_gtk_shell1
*/
static inline struct gtk_surface1 *
gtk_shell1_get_gtk_surface(struct gtk_shell1 *gtk_shell1, struct wl_surface *surface)
{
struct wl_proxy *gtk_surface;
gtk_surface = wl_proxy_marshal_constructor((struct wl_proxy *) gtk_shell1,
GTK_SHELL1_GET_GTK_SURFACE, &gtk_surface1_interface, NULL, surface);
return (struct gtk_surface1 *) gtk_surface;
}
/**
* @ingroup iface_gtk_shell1
*/
static inline void
gtk_shell1_set_startup_id(struct gtk_shell1 *gtk_shell1, const char *startup_id)
{
wl_proxy_marshal((struct wl_proxy *) gtk_shell1,
GTK_SHELL1_SET_STARTUP_ID, startup_id);
}
/**
* @ingroup iface_gtk_shell1
*/
static inline void
gtk_shell1_system_bell(struct gtk_shell1 *gtk_shell1, struct gtk_surface1 *surface)
{
wl_proxy_marshal((struct wl_proxy *) gtk_shell1,
GTK_SHELL1_SYSTEM_BELL, surface);
}
/**
* @ingroup iface_gtk_shell1
*/
static inline void
gtk_shell1_notify_launch(struct gtk_shell1 *gtk_shell1, const char *startup_id)
{
wl_proxy_marshal((struct wl_proxy *) gtk_shell1,
GTK_SHELL1_NOTIFY_LAUNCH, startup_id);
}
#ifndef GTK_SURFACE1_STATE_ENUM
#define GTK_SURFACE1_STATE_ENUM
enum gtk_surface1_state {
GTK_SURFACE1_STATE_TILED = 1,
/**
* @since 2
*/
GTK_SURFACE1_STATE_TILED_TOP = 2,
/**
* @since 2
*/
GTK_SURFACE1_STATE_TILED_RIGHT = 3,
/**
* @since 2
*/
GTK_SURFACE1_STATE_TILED_BOTTOM = 4,
/**
* @since 2
*/
GTK_SURFACE1_STATE_TILED_LEFT = 5,
};
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION 2
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION 2
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION 2
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION 2
#endif /* GTK_SURFACE1_STATE_ENUM */
#ifndef GTK_SURFACE1_EDGE_CONSTRAINT_ENUM
#define GTK_SURFACE1_EDGE_CONSTRAINT_ENUM
enum gtk_surface1_edge_constraint {
GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP = 1,
GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT = 2,
GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM = 3,
GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT = 4,
};
#endif /* GTK_SURFACE1_EDGE_CONSTRAINT_ENUM */
#ifndef GTK_SURFACE1_GESTURE_ENUM
#define GTK_SURFACE1_GESTURE_ENUM
enum gtk_surface1_gesture {
GTK_SURFACE1_GESTURE_DOUBLE_CLICK = 1,
GTK_SURFACE1_GESTURE_RIGHT_CLICK = 2,
GTK_SURFACE1_GESTURE_MIDDLE_CLICK = 3,
};
#endif /* GTK_SURFACE1_GESTURE_ENUM */
#ifndef GTK_SURFACE1_ERROR_ENUM
#define GTK_SURFACE1_ERROR_ENUM
enum gtk_surface1_error {
GTK_SURFACE1_ERROR_INVALID_GESTURE = 0,
};
#endif /* GTK_SURFACE1_ERROR_ENUM */
/**
* @ingroup iface_gtk_surface1
* @struct gtk_surface1_listener
*/
struct gtk_surface1_listener {
/**
*/
void (*configure)(void *data,
struct gtk_surface1 *gtk_surface1,
struct wl_array *states);
/**
* @since 2
*/
void (*configure_edges)(void *data,
struct gtk_surface1 *gtk_surface1,
struct wl_array *constraints);
};
/**
* @ingroup iface_gtk_surface1
*/
static inline int
gtk_surface1_add_listener(struct gtk_surface1 *gtk_surface1,
const struct gtk_surface1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) gtk_surface1,
(void (**)(void)) listener, data);
}
#define GTK_SURFACE1_SET_DBUS_PROPERTIES 0
#define GTK_SURFACE1_SET_MODAL 1
#define GTK_SURFACE1_UNSET_MODAL 2
#define GTK_SURFACE1_PRESENT 3
#define GTK_SURFACE1_REQUEST_FOCUS 4
#define GTK_SURFACE1_RELEASE 5
#define GTK_SURFACE1_TITLEBAR_GESTURE 6
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_CONFIGURE_SINCE_VERSION 1
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION 2
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_SET_DBUS_PROPERTIES_SINCE_VERSION 1
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_SET_MODAL_SINCE_VERSION 1
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_UNSET_MODAL_SINCE_VERSION 1
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_PRESENT_SINCE_VERSION 1
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_REQUEST_FOCUS_SINCE_VERSION 3
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_RELEASE_SINCE_VERSION 4
/**
* @ingroup iface_gtk_surface1
*/
#define GTK_SURFACE1_TITLEBAR_GESTURE_SINCE_VERSION 5
/** @ingroup iface_gtk_surface1 */
static inline void
gtk_surface1_set_user_data(struct gtk_surface1 *gtk_surface1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) gtk_surface1, user_data);
}
/** @ingroup iface_gtk_surface1 */
static inline void *
gtk_surface1_get_user_data(struct gtk_surface1 *gtk_surface1)
{
return wl_proxy_get_user_data((struct wl_proxy *) gtk_surface1);
}
static inline uint32_t
gtk_surface1_get_version(struct gtk_surface1 *gtk_surface1)
{
return wl_proxy_get_version((struct wl_proxy *) gtk_surface1);
}
/** @ingroup iface_gtk_surface1 */
static inline void
gtk_surface1_destroy(struct gtk_surface1 *gtk_surface1)
{
wl_proxy_destroy((struct wl_proxy *) gtk_surface1);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_set_dbus_properties(struct gtk_surface1 *gtk_surface1, const char *application_id, const char *app_menu_path, const char *menubar_path, const char *window_object_path, const char *application_object_path, const char *unique_bus_name)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_SET_DBUS_PROPERTIES, application_id, app_menu_path, menubar_path, window_object_path, application_object_path, unique_bus_name);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_set_modal(struct gtk_surface1 *gtk_surface1)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_SET_MODAL);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_unset_modal(struct gtk_surface1 *gtk_surface1)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_UNSET_MODAL);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_present(struct gtk_surface1 *gtk_surface1, uint32_t time)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_PRESENT, time);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_request_focus(struct gtk_surface1 *gtk_surface1, const char *startup_id)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_REQUEST_FOCUS, startup_id);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_release(struct gtk_surface1 *gtk_surface1)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_RELEASE);
wl_proxy_destroy((struct wl_proxy *) gtk_surface1);
}
/**
* @ingroup iface_gtk_surface1
*/
static inline void
gtk_surface1_titlebar_gesture(struct gtk_surface1 *gtk_surface1, uint32_t serial, struct wl_seat *seat, uint32_t gesture)
{
wl_proxy_marshal((struct wl_proxy *) gtk_surface1,
GTK_SURFACE1_TITLEBAR_GESTURE, serial, seat, gesture);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,73 @@
/* Generated by wayland-scanner 1.19.0 */
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface gtk_surface1_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
static const struct wl_interface *gtk_types[] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&gtk_surface1_interface,
&wl_surface_interface,
&gtk_surface1_interface,
NULL,
&wl_seat_interface,
NULL,
};
static const struct wl_message gtk_shell1_requests[] = {
{ "get_gtk_surface", "no", gtk_types + 6 },
{ "set_startup_id", "?s", gtk_types + 0 },
{ "system_bell", "?o", gtk_types + 8 },
{ "notify_launch", "3s", gtk_types + 0 },
};
static const struct wl_message gtk_shell1_events[] = {
{ "capabilities", "u", gtk_types + 0 },
};
WL_PRIVATE const struct wl_interface gtk_shell1_interface = {
"gtk_shell1", 5,
4, gtk_shell1_requests,
1, gtk_shell1_events,
};
static const struct wl_message gtk_surface1_requests[] = {
{ "set_dbus_properties", "?s?s?s?s?s?s", gtk_types + 0 },
{ "set_modal", "", gtk_types + 0 },
{ "unset_modal", "", gtk_types + 0 },
{ "present", "u", gtk_types + 0 },
{ "request_focus", "3?s", gtk_types + 0 },
{ "release", "4", gtk_types + 0 },
{ "titlebar_gesture", "5uou", gtk_types + 9 },
};
static const struct wl_message gtk_surface1_events[] = {
{ "configure", "a", gtk_types + 0 },
{ "configure_edges", "2a", gtk_types + 0 },
};
WL_PRIVATE const struct wl_interface gtk_surface1_interface = {
"gtk_surface1", 5,
7, gtk_surface1_requests,
2, gtk_surface1_events,
};

View File

@@ -0,0 +1,590 @@
/* Generated by wayland-scanner 1.19.0 */
#ifndef WP_PRIMARY_SELECTION_UNSTABLE_V1_CLIENT_PROTOCOL_H
#define WP_PRIMARY_SELECTION_UNSTABLE_V1_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_wp_primary_selection_unstable_v1 The wp_primary_selection_unstable_v1 protocol
* Primary selection protocol
*
* @section page_desc_wp_primary_selection_unstable_v1 Description
*
* This protocol provides the ability to have a primary selection device to
* match that of the X server. This primary selection is a shortcut to the
* common clipboard selection, where text just needs to be selected in order
* to allow copying it elsewhere. The de facto way to perform this action
* is the middle mouse button, although it is not limited to this one.
*
* Clients wishing to honor primary selection should create a primary
* selection source and set it as the selection through
* wp_primary_selection_device.set_selection whenever the text selection
* changes. In order to minimize calls in pointer-driven text selection,
* it should happen only once after the operation finished. Similarly,
* a NULL source should be set when text is unselected.
*
* wp_primary_selection_offer objects are first announced through the
* wp_primary_selection_device.data_offer event. Immediately after this event,
* the primary data offer will emit wp_primary_selection_offer.offer events
* to let know of the mime types being offered.
*
* When the primary selection changes, the client with the keyboard focus
* will receive wp_primary_selection_device.selection events. Only the client
* with the keyboard focus will receive such events with a non-NULL
* wp_primary_selection_offer. Across keyboard focus changes, previously
* focused clients will receive wp_primary_selection_device.events with a
* NULL wp_primary_selection_offer.
*
* In order to request the primary selection data, the client must pass
* a recent serial pertaining to the press event that is triggering the
* operation, if the compositor deems the serial valid and recent, the
* wp_primary_selection_source.send event will happen in the other end
* to let the transfer begin. The client owning the primary selection
* should write the requested data, and close the file descriptor
* immediately.
*
* If the primary selection owner client disappeared during the transfer,
* the client reading the data will receive a
* wp_primary_selection_device.selection event with a NULL
* wp_primary_selection_offer, the client should take this as a hint
* to finish the reads related to the no longer existing offer.
*
* The primary selection owner should be checking for errors during
* writes, merely cancelling the ongoing transfer if any happened.
*
* @section page_ifaces_wp_primary_selection_unstable_v1 Interfaces
* - @subpage page_iface_zwp_primary_selection_device_manager_v1 - X primary selection emulation
* - @subpage page_iface_zwp_primary_selection_device_v1 -
* - @subpage page_iface_zwp_primary_selection_offer_v1 - offer to transfer primary selection contents
* - @subpage page_iface_zwp_primary_selection_source_v1 - offer to replace the contents of the primary selection
* @section page_copyright_wp_primary_selection_unstable_v1 Copyright
* <pre>
*
* Copyright © 2015, 2016 Red Hat
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </pre>
*/
struct wl_seat;
struct zwp_primary_selection_device_manager_v1;
struct zwp_primary_selection_device_v1;
struct zwp_primary_selection_offer_v1;
struct zwp_primary_selection_source_v1;
#ifndef ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_INTERFACE
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_INTERFACE
/**
* @page page_iface_zwp_primary_selection_device_manager_v1 zwp_primary_selection_device_manager_v1
* @section page_iface_zwp_primary_selection_device_manager_v1_desc Description
*
* The primary selection device manager is a singleton global object that
* provides access to the primary selection. It allows to create
* wp_primary_selection_source objects, as well as retrieving the per-seat
* wp_primary_selection_device objects.
* @section page_iface_zwp_primary_selection_device_manager_v1_api API
* See @ref iface_zwp_primary_selection_device_manager_v1.
*/
/**
* @defgroup iface_zwp_primary_selection_device_manager_v1 The zwp_primary_selection_device_manager_v1 interface
*
* The primary selection device manager is a singleton global object that
* provides access to the primary selection. It allows to create
* wp_primary_selection_source objects, as well as retrieving the per-seat
* wp_primary_selection_device objects.
*/
extern const struct wl_interface zwp_primary_selection_device_manager_v1_interface;
#endif
#ifndef ZWP_PRIMARY_SELECTION_DEVICE_V1_INTERFACE
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_INTERFACE
/**
* @page page_iface_zwp_primary_selection_device_v1 zwp_primary_selection_device_v1
* @section page_iface_zwp_primary_selection_device_v1_api API
* See @ref iface_zwp_primary_selection_device_v1.
*/
/**
* @defgroup iface_zwp_primary_selection_device_v1 The zwp_primary_selection_device_v1 interface
*/
extern const struct wl_interface zwp_primary_selection_device_v1_interface;
#endif
#ifndef ZWP_PRIMARY_SELECTION_OFFER_V1_INTERFACE
#define ZWP_PRIMARY_SELECTION_OFFER_V1_INTERFACE
/**
* @page page_iface_zwp_primary_selection_offer_v1 zwp_primary_selection_offer_v1
* @section page_iface_zwp_primary_selection_offer_v1_desc Description
*
* A wp_primary_selection_offer represents an offer to transfer the contents
* of the primary selection clipboard to the client. Similar to
* wl_data_offer, the offer also describes the mime types that the data can
* be converted to and provides the mechanisms for transferring the data
* directly to the client.
* @section page_iface_zwp_primary_selection_offer_v1_api API
* See @ref iface_zwp_primary_selection_offer_v1.
*/
/**
* @defgroup iface_zwp_primary_selection_offer_v1 The zwp_primary_selection_offer_v1 interface
*
* A wp_primary_selection_offer represents an offer to transfer the contents
* of the primary selection clipboard to the client. Similar to
* wl_data_offer, the offer also describes the mime types that the data can
* be converted to and provides the mechanisms for transferring the data
* directly to the client.
*/
extern const struct wl_interface zwp_primary_selection_offer_v1_interface;
#endif
#ifndef ZWP_PRIMARY_SELECTION_SOURCE_V1_INTERFACE
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_INTERFACE
/**
* @page page_iface_zwp_primary_selection_source_v1 zwp_primary_selection_source_v1
* @section page_iface_zwp_primary_selection_source_v1_desc Description
*
* The source side of a wp_primary_selection_offer, it provides a way to
* describe the offered data and respond to requests to transfer the
* requested contents of the primary selection clipboard.
* @section page_iface_zwp_primary_selection_source_v1_api API
* See @ref iface_zwp_primary_selection_source_v1.
*/
/**
* @defgroup iface_zwp_primary_selection_source_v1 The zwp_primary_selection_source_v1 interface
*
* The source side of a wp_primary_selection_offer, it provides a way to
* describe the offered data and respond to requests to transfer the
* requested contents of the primary selection clipboard.
*/
extern const struct wl_interface zwp_primary_selection_source_v1_interface;
#endif
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_CREATE_SOURCE 0
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_GET_DEVICE 1
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_DESTROY 2
/**
* @ingroup iface_zwp_primary_selection_device_manager_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_CREATE_SOURCE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_device_manager_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_GET_DEVICE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_device_manager_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_primary_selection_device_manager_v1 */
static inline void
zwp_primary_selection_device_manager_v1_set_user_data(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_device_manager_v1, user_data);
}
/** @ingroup iface_zwp_primary_selection_device_manager_v1 */
static inline void *
zwp_primary_selection_device_manager_v1_get_user_data(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_device_manager_v1);
}
static inline uint32_t
zwp_primary_selection_device_manager_v1_get_version(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_manager_v1);
}
/**
* @ingroup iface_zwp_primary_selection_device_manager_v1
*
* Create a new primary selection source.
*/
static inline struct zwp_primary_selection_source_v1 *
zwp_primary_selection_device_manager_v1_create_source(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) zwp_primary_selection_device_manager_v1,
ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_CREATE_SOURCE, &zwp_primary_selection_source_v1_interface, NULL);
return (struct zwp_primary_selection_source_v1 *) id;
}
/**
* @ingroup iface_zwp_primary_selection_device_manager_v1
*
* Create a new data device for a given seat.
*/
static inline struct zwp_primary_selection_device_v1 *
zwp_primary_selection_device_manager_v1_get_device(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1, struct wl_seat *seat)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) zwp_primary_selection_device_manager_v1,
ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_GET_DEVICE, &zwp_primary_selection_device_v1_interface, NULL, seat);
return (struct zwp_primary_selection_device_v1 *) id;
}
/**
* @ingroup iface_zwp_primary_selection_device_manager_v1
*
* Destroy the primary selection device manager.
*/
static inline void
zwp_primary_selection_device_manager_v1_destroy(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_device_manager_v1,
ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) zwp_primary_selection_device_manager_v1);
}
/**
* @ingroup iface_zwp_primary_selection_device_v1
* @struct zwp_primary_selection_device_v1_listener
*/
struct zwp_primary_selection_device_v1_listener {
/**
* introduce a new wp_primary_selection_offer
*
* Introduces a new wp_primary_selection_offer object that may be
* used to receive the current primary selection. Immediately
* following this event, the new wp_primary_selection_offer object
* will send wp_primary_selection_offer.offer events to describe
* the offered mime types.
*/
void (*data_offer)(void *data,
struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1,
struct zwp_primary_selection_offer_v1 *offer);
/**
* advertise a new primary selection
*
* The wp_primary_selection_device.selection event is sent to
* notify the client of a new primary selection. This event is sent
* after the wp_primary_selection.data_offer event introducing this
* object, and after the offer has announced its mimetypes through
* wp_primary_selection_offer.offer.
*
* The data_offer is valid until a new offer or NULL is received or
* until the client loses keyboard focus. The client must destroy
* the previous selection data_offer, if any, upon receiving this
* event.
*/
void (*selection)(void *data,
struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1,
struct zwp_primary_selection_offer_v1 *id);
};
/**
* @ingroup iface_zwp_primary_selection_device_v1
*/
static inline int
zwp_primary_selection_device_v1_add_listener(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1,
const struct zwp_primary_selection_device_v1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_primary_selection_device_v1,
(void (**)(void)) listener, data);
}
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_SET_SELECTION 0
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_DESTROY 1
/**
* @ingroup iface_zwp_primary_selection_device_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_DATA_OFFER_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_device_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_SELECTION_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_device_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_SET_SELECTION_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_device_v1
*/
#define ZWP_PRIMARY_SELECTION_DEVICE_V1_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_primary_selection_device_v1 */
static inline void
zwp_primary_selection_device_v1_set_user_data(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_device_v1, user_data);
}
/** @ingroup iface_zwp_primary_selection_device_v1 */
static inline void *
zwp_primary_selection_device_v1_get_user_data(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_device_v1);
}
static inline uint32_t
zwp_primary_selection_device_v1_get_version(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_v1);
}
/**
* @ingroup iface_zwp_primary_selection_device_v1
*
* Replaces the current selection. The previous owner of the primary
* selection will receive a wp_primary_selection_source.cancelled event.
*
* To unset the selection, set the source to NULL.
*/
static inline void
zwp_primary_selection_device_v1_set_selection(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, struct zwp_primary_selection_source_v1 *source, uint32_t serial)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_device_v1,
ZWP_PRIMARY_SELECTION_DEVICE_V1_SET_SELECTION, source, serial);
}
/**
* @ingroup iface_zwp_primary_selection_device_v1
*
* Destroy the primary selection device.
*/
static inline void
zwp_primary_selection_device_v1_destroy(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_device_v1,
ZWP_PRIMARY_SELECTION_DEVICE_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) zwp_primary_selection_device_v1);
}
/**
* @ingroup iface_zwp_primary_selection_offer_v1
* @struct zwp_primary_selection_offer_v1_listener
*/
struct zwp_primary_selection_offer_v1_listener {
/**
* advertise offered mime type
*
* Sent immediately after creating announcing the
* wp_primary_selection_offer through
* wp_primary_selection_device.data_offer. One event is sent per
* offered mime type.
*/
void (*offer)(void *data,
struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1,
const char *mime_type);
};
/**
* @ingroup iface_zwp_primary_selection_offer_v1
*/
static inline int
zwp_primary_selection_offer_v1_add_listener(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1,
const struct zwp_primary_selection_offer_v1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_primary_selection_offer_v1,
(void (**)(void)) listener, data);
}
#define ZWP_PRIMARY_SELECTION_OFFER_V1_RECEIVE 0
#define ZWP_PRIMARY_SELECTION_OFFER_V1_DESTROY 1
/**
* @ingroup iface_zwp_primary_selection_offer_v1
*/
#define ZWP_PRIMARY_SELECTION_OFFER_V1_OFFER_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_offer_v1
*/
#define ZWP_PRIMARY_SELECTION_OFFER_V1_RECEIVE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_offer_v1
*/
#define ZWP_PRIMARY_SELECTION_OFFER_V1_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_primary_selection_offer_v1 */
static inline void
zwp_primary_selection_offer_v1_set_user_data(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_offer_v1, user_data);
}
/** @ingroup iface_zwp_primary_selection_offer_v1 */
static inline void *
zwp_primary_selection_offer_v1_get_user_data(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_offer_v1);
}
static inline uint32_t
zwp_primary_selection_offer_v1_get_version(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_offer_v1);
}
/**
* @ingroup iface_zwp_primary_selection_offer_v1
*
* To transfer the contents of the primary selection clipboard, the client
* issues this request and indicates the mime type that it wants to
* receive. The transfer happens through the passed file descriptor
* (typically created with the pipe system call). The source client writes
* the data in the mime type representation requested and then closes the
* file descriptor.
*
* The receiving client reads from the read end of the pipe until EOF and
* closes its end, at which point the transfer is complete.
*/
static inline void
zwp_primary_selection_offer_v1_receive(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1, const char *mime_type, int32_t fd)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_offer_v1,
ZWP_PRIMARY_SELECTION_OFFER_V1_RECEIVE, mime_type, fd);
}
/**
* @ingroup iface_zwp_primary_selection_offer_v1
*
* Destroy the primary selection offer.
*/
static inline void
zwp_primary_selection_offer_v1_destroy(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_offer_v1,
ZWP_PRIMARY_SELECTION_OFFER_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) zwp_primary_selection_offer_v1);
}
/**
* @ingroup iface_zwp_primary_selection_source_v1
* @struct zwp_primary_selection_source_v1_listener
*/
struct zwp_primary_selection_source_v1_listener {
/**
* send the primary selection contents
*
* Request for the current primary selection contents from the
* client. Send the specified mime type over the passed file
* descriptor, then close it.
*/
void (*send)(void *data,
struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1,
const char *mime_type,
int32_t fd);
/**
* request for primary selection contents was canceled
*
* This primary selection source is no longer valid. The client
* should clean up and destroy this primary selection source.
*/
void (*cancelled)(void *data,
struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1);
};
/**
* @ingroup iface_zwp_primary_selection_source_v1
*/
static inline int
zwp_primary_selection_source_v1_add_listener(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1,
const struct zwp_primary_selection_source_v1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_primary_selection_source_v1,
(void (**)(void)) listener, data);
}
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_OFFER 0
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_DESTROY 1
/**
* @ingroup iface_zwp_primary_selection_source_v1
*/
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_SEND_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_source_v1
*/
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_CANCELLED_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_source_v1
*/
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_OFFER_SINCE_VERSION 1
/**
* @ingroup iface_zwp_primary_selection_source_v1
*/
#define ZWP_PRIMARY_SELECTION_SOURCE_V1_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_primary_selection_source_v1 */
static inline void
zwp_primary_selection_source_v1_set_user_data(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_source_v1, user_data);
}
/** @ingroup iface_zwp_primary_selection_source_v1 */
static inline void *
zwp_primary_selection_source_v1_get_user_data(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_source_v1);
}
static inline uint32_t
zwp_primary_selection_source_v1_get_version(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_source_v1);
}
/**
* @ingroup iface_zwp_primary_selection_source_v1
*
* This request adds a mime type to the set of mime types advertised to
* targets. Can be called several times to offer multiple types.
*/
static inline void
zwp_primary_selection_source_v1_offer(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1, const char *mime_type)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_source_v1,
ZWP_PRIMARY_SELECTION_SOURCE_V1_OFFER, mime_type);
}
/**
* @ingroup iface_zwp_primary_selection_source_v1
*
* Destroy the primary selection source.
*/
static inline void
zwp_primary_selection_source_v1_destroy(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
{
wl_proxy_marshal((struct wl_proxy *) zwp_primary_selection_source_v1,
ZWP_PRIMARY_SELECTION_SOURCE_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) zwp_primary_selection_source_v1);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,115 @@
/* Generated by wayland-scanner 1.19.0 */
/*
* Copyright © 2015, 2016 Red Hat
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface zwp_primary_selection_device_v1_interface;
extern const struct wl_interface zwp_primary_selection_offer_v1_interface;
extern const struct wl_interface zwp_primary_selection_source_v1_interface;
static const struct wl_interface *wp_primary_selection_unstable_v1_types[] = {
NULL,
NULL,
&zwp_primary_selection_source_v1_interface,
&zwp_primary_selection_device_v1_interface,
&wl_seat_interface,
&zwp_primary_selection_source_v1_interface,
NULL,
&zwp_primary_selection_offer_v1_interface,
&zwp_primary_selection_offer_v1_interface,
};
static const struct wl_message zwp_primary_selection_device_manager_v1_requests[] = {
{ "create_source", "n", wp_primary_selection_unstable_v1_types + 2 },
{ "get_device", "no", wp_primary_selection_unstable_v1_types + 3 },
{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_primary_selection_device_manager_v1_interface = {
"zwp_primary_selection_device_manager_v1", 1,
3, zwp_primary_selection_device_manager_v1_requests,
0, NULL,
};
static const struct wl_message zwp_primary_selection_device_v1_requests[] = {
{ "set_selection", "?ou", wp_primary_selection_unstable_v1_types + 5 },
{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
};
static const struct wl_message zwp_primary_selection_device_v1_events[] = {
{ "data_offer", "n", wp_primary_selection_unstable_v1_types + 7 },
{ "selection", "?o", wp_primary_selection_unstable_v1_types + 8 },
};
WL_PRIVATE const struct wl_interface zwp_primary_selection_device_v1_interface = {
"zwp_primary_selection_device_v1", 1,
2, zwp_primary_selection_device_v1_requests,
2, zwp_primary_selection_device_v1_events,
};
static const struct wl_message zwp_primary_selection_offer_v1_requests[] = {
{ "receive", "sh", wp_primary_selection_unstable_v1_types + 0 },
{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
};
static const struct wl_message zwp_primary_selection_offer_v1_events[] = {
{ "offer", "s", wp_primary_selection_unstable_v1_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_primary_selection_offer_v1_interface = {
"zwp_primary_selection_offer_v1", 1,
2, zwp_primary_selection_offer_v1_requests,
1, zwp_primary_selection_offer_v1_events,
};
static const struct wl_message zwp_primary_selection_source_v1_requests[] = {
{ "offer", "s", wp_primary_selection_unstable_v1_types + 0 },
{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
};
static const struct wl_message zwp_primary_selection_source_v1_events[] = {
{ "send", "sh", wp_primary_selection_unstable_v1_types + 0 },
{ "cancelled", "", wp_primary_selection_unstable_v1_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_primary_selection_source_v1_interface = {
"zwp_primary_selection_source_v1", 1,
2, zwp_primary_selection_source_v1_requests,
2, zwp_primary_selection_source_v1_events,
};

View File

@@ -0,0 +1,413 @@
/* Generated by wayland-scanner 1.18.0 */
#ifndef XDG_ACTIVATION_V1_CLIENT_PROTOCOL_H
#define XDG_ACTIVATION_V1_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_xdg_activation_v1 The xdg_activation_v1 protocol
* Protocol for requesting activation of surfaces
*
* @section page_desc_xdg_activation_v1 Description
*
* The way for a client to pass focus to another toplevel is as follows.
*
* The client that intends to activate another toplevel uses the
* xdg_activation_v1.get_activation_token request to get an activation token.
* This token is then forwarded to the client, which is supposed to activate
* one of its surfaces, through a separate band of communication.
*
* One established way of doing this is through the XDG_ACTIVATION_TOKEN
* environment variable of a newly launched child process. The child process
* should unset the environment variable again right after reading it out in
* order to avoid propagating it to other child processes.
*
* Another established way exists for Applications implementing the D-Bus
* interface org.freedesktop.Application, which should get their token under
* XDG_ACTIVATION_TOKEN on their platform_data.
*
* In general activation tokens may be transferred across clients through
* means not described in this protocol.
*
* The client to be activated will then pass the token
* it received to the xdg_activation_v1.activate request. The compositor can
* then use this token to decide how to react to the activation request.
*
* The token the activating client gets may be ineffective either already at
* the time it receives it, for example if it was not focused, for focus
* stealing prevention. The activating client will have no way to discover
* the validity of the token, and may still forward it to the to be activated
* client.
*
* The created activation token may optionally get information attached to it
* that can be used by the compositor to identify the application that we
* intend to activate. This can for example be used to display a visual hint
* about what application is being started.
*
* Warning! The protocol described in this file is currently in the testing
* phase. Backward compatible changes may be added together with the
* corresponding interface version bump. Backward incompatible changes can
* only be done by creating a new major version of the extension.
*
* @section page_ifaces_xdg_activation_v1 Interfaces
* - @subpage page_iface_xdg_activation_v1 - interface for activating surfaces
* - @subpage page_iface_xdg_activation_token_v1 - an exported activation handle
* @section page_copyright_xdg_activation_v1 Copyright
* <pre>
*
* Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
* Copyright © 2020 Carlos Garnacho <carlosg@gnome.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </pre>
*/
struct wl_seat;
struct wl_surface;
struct xdg_activation_token_v1;
struct xdg_activation_v1;
/**
* @page page_iface_xdg_activation_v1 xdg_activation_v1
* @section page_iface_xdg_activation_v1_desc Description
*
* A global interface used for informing the compositor about applications
* being activated or started, or for applications to request to be
* activated.
* @section page_iface_xdg_activation_v1_api API
* See @ref iface_xdg_activation_v1.
*/
/**
* @defgroup iface_xdg_activation_v1 The xdg_activation_v1 interface
*
* A global interface used for informing the compositor about applications
* being activated or started, or for applications to request to be
* activated.
*/
extern const struct wl_interface xdg_activation_v1_interface;
/**
* @page page_iface_xdg_activation_token_v1 xdg_activation_token_v1
* @section page_iface_xdg_activation_token_v1_desc Description
*
* An object for setting up a token and receiving a token handle that can
* be passed as an activation token to another client.
*
* The object is created using the xdg_activation_v1.get_activation_token
* request. This object should then be populated with the app_id, surface
* and serial information and committed. The compositor shall then issue a
* done event with the token. In case the request's parameters are invalid,
* the compositor will provide an invalid token.
* @section page_iface_xdg_activation_token_v1_api API
* See @ref iface_xdg_activation_token_v1.
*/
/**
* @defgroup iface_xdg_activation_token_v1 The xdg_activation_token_v1 interface
*
* An object for setting up a token and receiving a token handle that can
* be passed as an activation token to another client.
*
* The object is created using the xdg_activation_v1.get_activation_token
* request. This object should then be populated with the app_id, surface
* and serial information and committed. The compositor shall then issue a
* done event with the token. In case the request's parameters are invalid,
* the compositor will provide an invalid token.
*/
extern const struct wl_interface xdg_activation_token_v1_interface;
#define XDG_ACTIVATION_V1_DESTROY 0
#define XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN 1
#define XDG_ACTIVATION_V1_ACTIVATE 2
/**
* @ingroup iface_xdg_activation_v1
*/
#define XDG_ACTIVATION_V1_DESTROY_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_v1
*/
#define XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_v1
*/
#define XDG_ACTIVATION_V1_ACTIVATE_SINCE_VERSION 1
/** @ingroup iface_xdg_activation_v1 */
static inline void
xdg_activation_v1_set_user_data(struct xdg_activation_v1 *xdg_activation_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) xdg_activation_v1, user_data);
}
/** @ingroup iface_xdg_activation_v1 */
static inline void *
xdg_activation_v1_get_user_data(struct xdg_activation_v1 *xdg_activation_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) xdg_activation_v1);
}
static inline uint32_t
xdg_activation_v1_get_version(struct xdg_activation_v1 *xdg_activation_v1)
{
return wl_proxy_get_version((struct wl_proxy *) xdg_activation_v1);
}
/**
* @ingroup iface_xdg_activation_v1
*
* Notify the compositor that the xdg_activation object will no longer be
* used.
*
* The child objects created via this interface are unaffected and should
* be destroyed separately.
*/
static inline void
xdg_activation_v1_destroy(struct xdg_activation_v1 *xdg_activation_v1)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_v1,
XDG_ACTIVATION_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) xdg_activation_v1);
}
/**
* @ingroup iface_xdg_activation_v1
*
* Creates an xdg_activation_token_v1 object that will provide
* the initiating client with a unique token for this activation. This
* token should be offered to the clients to be activated.
*/
static inline struct xdg_activation_token_v1 *
xdg_activation_v1_get_activation_token(struct xdg_activation_v1 *xdg_activation_v1)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) xdg_activation_v1,
XDG_ACTIVATION_V1_GET_ACTIVATION_TOKEN, &xdg_activation_token_v1_interface, NULL);
return (struct xdg_activation_token_v1 *) id;
}
/**
* @ingroup iface_xdg_activation_v1
*
* Requests surface activation. It's up to the compositor to display
* this information as desired, for example by placing the surface above
* the rest.
*
* The compositor may know who requested this by checking the activation
* token and might decide not to follow through with the activation if it's
* considered unwanted.
*
* Compositors can ignore unknown activation tokens when an invalid
* token is passed.
*/
static inline void
xdg_activation_v1_activate(struct xdg_activation_v1 *xdg_activation_v1, const char *token, struct wl_surface *surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_v1,
XDG_ACTIVATION_V1_ACTIVATE, token, surface);
}
#ifndef XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM
#define XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM
enum xdg_activation_token_v1_error {
/**
* The token has already been used previously
*/
XDG_ACTIVATION_TOKEN_V1_ERROR_ALREADY_USED = 0,
};
#endif /* XDG_ACTIVATION_TOKEN_V1_ERROR_ENUM */
/**
* @ingroup iface_xdg_activation_token_v1
* @struct xdg_activation_token_v1_listener
*/
struct xdg_activation_token_v1_listener {
/**
* the exported activation token
*
* The 'done' event contains the unique token of this activation
* request and notifies that the provider is done.
* @param token the exported activation token
*/
void (*done)(void *data,
struct xdg_activation_token_v1 *xdg_activation_token_v1,
const char *token);
};
/**
* @ingroup iface_xdg_activation_token_v1
*/
static inline int
xdg_activation_token_v1_add_listener(struct xdg_activation_token_v1 *xdg_activation_token_v1,
const struct xdg_activation_token_v1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) xdg_activation_token_v1,
(void (**)(void)) listener, data);
}
#define XDG_ACTIVATION_TOKEN_V1_SET_SERIAL 0
#define XDG_ACTIVATION_TOKEN_V1_SET_APP_ID 1
#define XDG_ACTIVATION_TOKEN_V1_SET_SURFACE 2
#define XDG_ACTIVATION_TOKEN_V1_COMMIT 3
#define XDG_ACTIVATION_TOKEN_V1_DESTROY 4
/**
* @ingroup iface_xdg_activation_token_v1
*/
#define XDG_ACTIVATION_TOKEN_V1_DONE_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_token_v1
*/
#define XDG_ACTIVATION_TOKEN_V1_SET_SERIAL_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_token_v1
*/
#define XDG_ACTIVATION_TOKEN_V1_SET_APP_ID_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_token_v1
*/
#define XDG_ACTIVATION_TOKEN_V1_SET_SURFACE_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_token_v1
*/
#define XDG_ACTIVATION_TOKEN_V1_COMMIT_SINCE_VERSION 1
/**
* @ingroup iface_xdg_activation_token_v1
*/
#define XDG_ACTIVATION_TOKEN_V1_DESTROY_SINCE_VERSION 1
/** @ingroup iface_xdg_activation_token_v1 */
static inline void
xdg_activation_token_v1_set_user_data(struct xdg_activation_token_v1 *xdg_activation_token_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) xdg_activation_token_v1, user_data);
}
/** @ingroup iface_xdg_activation_token_v1 */
static inline void *
xdg_activation_token_v1_get_user_data(struct xdg_activation_token_v1 *xdg_activation_token_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) xdg_activation_token_v1);
}
static inline uint32_t
xdg_activation_token_v1_get_version(struct xdg_activation_token_v1 *xdg_activation_token_v1)
{
return wl_proxy_get_version((struct wl_proxy *) xdg_activation_token_v1);
}
/**
* @ingroup iface_xdg_activation_token_v1
*
* Provides information about the seat and serial event that requested the
* token.
*
* The serial can come from an input or focus event. For instance, if a
* click triggers the launch of a third-party client, the launcher client
* should send a set_serial request with the serial and seat from the
* wl_pointer.button event.
*
* Some compositors might refuse to activate toplevels when the token
* doesn't have a valid and recent enough event serial.
*
* Must be sent before commit. This information is optional.
*/
static inline void
xdg_activation_token_v1_set_serial(struct xdg_activation_token_v1 *xdg_activation_token_v1, uint32_t serial, struct wl_seat *seat)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_token_v1,
XDG_ACTIVATION_TOKEN_V1_SET_SERIAL, serial, seat);
}
/**
* @ingroup iface_xdg_activation_token_v1
*
* The requesting client can specify an app_id to associate the token
* being created with it.
*
* Must be sent before commit. This information is optional.
*/
static inline void
xdg_activation_token_v1_set_app_id(struct xdg_activation_token_v1 *xdg_activation_token_v1, const char *app_id)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_token_v1,
XDG_ACTIVATION_TOKEN_V1_SET_APP_ID, app_id);
}
/**
* @ingroup iface_xdg_activation_token_v1
*
* This request sets the surface requesting the activation. Note, this is
* different from the surface that will be activated.
*
* Some compositors might refuse to activate toplevels when the token
* doesn't have a requesting surface.
*
* Must be sent before commit. This information is optional.
*/
static inline void
xdg_activation_token_v1_set_surface(struct xdg_activation_token_v1 *xdg_activation_token_v1, struct wl_surface *surface)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_token_v1,
XDG_ACTIVATION_TOKEN_V1_SET_SURFACE, surface);
}
/**
* @ingroup iface_xdg_activation_token_v1
*
* Requests an activation token based on the different parameters that
* have been offered through set_serial, set_surface and set_app_id.
*/
static inline void
xdg_activation_token_v1_commit(struct xdg_activation_token_v1 *xdg_activation_token_v1)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_token_v1,
XDG_ACTIVATION_TOKEN_V1_COMMIT);
}
/**
* @ingroup iface_xdg_activation_token_v1
*
* Notify the compositor that the xdg_activation_token_v1 object will no
* longer be used.
*/
static inline void
xdg_activation_token_v1_destroy(struct xdg_activation_token_v1 *xdg_activation_token_v1)
{
wl_proxy_marshal((struct wl_proxy *) xdg_activation_token_v1,
XDG_ACTIVATION_TOKEN_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) xdg_activation_token_v1);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,84 @@
/* Generated by wayland-scanner 1.18.0 */
/*
* Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
* Copyright © 2020 Carlos Garnacho <carlosg@gnome.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_activation_token_v1_interface;
static const struct wl_interface *xdg_activation_v1_types[] = {
NULL,
&xdg_activation_token_v1_interface,
NULL,
&wl_surface_interface,
NULL,
&wl_seat_interface,
&wl_surface_interface,
};
static const struct wl_message xdg_activation_v1_requests[] = {
{ "destroy", "", xdg_activation_v1_types + 0 },
{ "get_activation_token", "n", xdg_activation_v1_types + 1 },
{ "activate", "so", xdg_activation_v1_types + 2 },
};
WL_PRIVATE const struct wl_interface xdg_activation_v1_interface = {
"xdg_activation_v1", 1,
3, xdg_activation_v1_requests,
0, NULL,
};
static const struct wl_message xdg_activation_token_v1_requests[] = {
{ "set_serial", "uo", xdg_activation_v1_types + 4 },
{ "set_app_id", "s", xdg_activation_v1_types + 0 },
{ "set_surface", "o", xdg_activation_v1_types + 6 },
{ "commit", "", xdg_activation_v1_types + 0 },
{ "destroy", "", xdg_activation_v1_types + 0 },
};
static const struct wl_message xdg_activation_token_v1_events[] = {
{ "done", "s", xdg_activation_v1_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_activation_token_v1_interface = {
"xdg_activation_token_v1", 1,
5, xdg_activation_token_v1_requests,
1, xdg_activation_token_v1_events,
};

View File

@@ -53,7 +53,9 @@ gtest/MetaspaceGtests.java#balanced-no-ccs initial_run generic-all
gtest/MetaspaceGtests.java#reclaim-aggressive-ndebug initial_run generic-all
gtest/LargePageGtests.java#use-large-pages initial_run linux-all,windows-all
gtest/NMTGtests.java JBR-5718 generic-all
gtest/NMTGtests.java#nmt-detail JBR-5718 generic-all
gtest/NMTGtests.java#nmt-off JBR-5718 generic-all
gtest/NMTGtests.java#nmt-summary JBR-5718 generic-all
gc/stress/TestReclaimStringsLeaksMemory.java initial_run windows-all
@@ -256,13 +258,11 @@ vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription
gc/shenandoah/mxbeans/TestChurnNotifications.java#aggressive NO_BUG macosx_all
runtime/cds/appcds/TestDumpClassListSource.java NO_BUG generic_all
runtime/cds/appcds/CommandLineFlagCombo.java NO_BUG generic_all
runtime/cds/appcds/TestDumpClassListSource.java JBR-6099 generic_all
runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveNoDefaultArchive.java NO_BUG generic_all
runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchiveUpgrade.java NO_BUG generic_all
runtime/cds/CheckDefaultArchiveFile.java NO_BUG generic_all
serviceability/jvmti/SetBreakpoint/TestManyBreakpoints.java NO_BUG linux_aarch64
vmTestbase/nsk/stress/thread/thread008.java initial_run windows-all
compiler/vectorapi/VectorRebracket128Test.java NO_BUG linux_aarch64

View File

@@ -785,3 +785,252 @@ jdk_containers_extended = \
:jdk_io \
:jdk_nio \
:jdk_svc
# Wayland tests to be executed with -Dawt.toolkit.name=WLToolkit
jdk_awt_wayland = \
:jdk_awt \
jb/java/awt/wayland \
-com/apple/eawt \
-com/apple/laf \
-sun/awt \
-java/awt/a11y \
-java/awt/applet \
-java/awt/BasicStroke/DashOffset.java \
-java/awt/BasicStroke/DashScaleMinWidth.java \
-java/awt/BasicStroke/DashZeroWidth.java \
-java/awt/BorderLayout \
-java/awt/Button \
-java/awt/Checkbox \
-java/awt/Choice \
-java/awt/Clipboard \
-java/awt/ColorClass/AlphaColorTest.java \
-java/awt/Component/7097771 \
-java/awt/Component/CompEventOnHiddenComponent \
-java/awt/Component/ComponentRedrawnTest.java \
-java/awt/Component/CreateImage \
-java/awt/Component/DimensionEncapsulation \
-java/awt/Component/F10TopToplevel \
-java/awt/Component/GetListenersTest.java \
-java/awt/Component/GetScreenLocTest \
-java/awt/Component/InsetsEncapsulation \
-java/awt/Component/isLightweightCrash \
-java/awt/Component/NativeInLightShow \
-java/awt/Component/NoUpdateUponShow \
-java/awt/Component/PaintAll \
-java/awt/Component/PrintAllXcheckJNI \
-java/awt/Component/RepaintTest.java \
-java/awt/Component/Revalidate \
-java/awt/Component/SetComponentsBounds \
-java/awt/Component/SetEnabledPerformance \
-java/awt/Component/TreeLockDeadlock \
-java/awt/Component/UpdatingBootTime \
-java/awt/Component/Validate \
-java/awt/ComponentOrientation \
-java/awt/Container \
-java/awt/Cursor \
-java/awt/datatransfer/Clipboard/GetContentsInterruptedTest.java \
-java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java \
-java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java \
-java/awt/datatransfer/CustomClassLoaderTransferTest/CustomClassLoaderTransferTest.java \
-java/awt/datatransfer/DataFlavor/DataFlavorRemoteTest.java \
-java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java \
-java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html \
-java/awt/datatransfer/ImageTransfer/ImageTransferTest.java \
-java/awt/datatransfer/Independence/IndependenceAWTTest.java \
-java/awt/datatransfer/Independence/IndependenceSwingTest.java \
-java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java \
-java/awt/datatransfer/SystemSelection/SystemSelectionAWTTest.java \
-java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java \
-java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java \
-java/awt/Debug \
-java/awt/Desktop \
-java/awt/Dialog \
-java/awt/dnd \
-java/awt/EmbeddedFrame \
-java/awt/event \
-java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java \
-java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java \
-java/awt/EventDispatchThread/PropertyPermissionOnEDT/PropertyPermissionOnEDT.java \
-java/awt/EventQueue/6980209/bug6980209.java \
-java/awt/FileDialog \
-java/awt/FlowLayout \
-java/awt/Focus/6378278 \
-java/awt/Focus/6382144 \
-java/awt/Focus/6401036 \
-java/awt/Focus/6981400 \
-java/awt/Focus/8000326 \
-java/awt/Focus/8013611 \
-java/awt/Focus/8073453 \
-java/awt/Focus/8282640 \
-java/awt/Focus/ActualFocusedWindowTest \
-java/awt/Focus/AppletInitialFocusTest \
-java/awt/Focus/AsyncUpFocusCycleTest.java \
-java/awt/Focus/AutoRequestFocusTest \
-java/awt/Focus/Cause \
-java/awt/Focus/ChildWindowFocusTest \
-java/awt/Focus/ChoiceFocus \
-java/awt/Focus/ClearGlobalFocusOwnerTest \
-java/awt/Focus/ClearLwQueueBreakTest \
-java/awt/Focus/ClearMostRecentFocusOwnerTest.java \
-java/awt/Focus/CloseDialogActivateOwnerTest \
-java/awt/Focus/ConsumedTabKeyTest.java \
-java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest \
-java/awt/Focus/ContainerFocusAutoTransferTest \
-java/awt/Focus/DeiconifiedFrameLoosesFocus \
-java/awt/Focus/DisposedWindow \
-java/awt/Focus/EventRetargetTest.java \
-java/awt/Focus/ExtraPropChangeNotifVetoingTest.java \
-java/awt/Focus/FocusEmbeddedFrameTest \
-java/awt/Focus/FocusForRemovedComponentTest.java \
-java/awt/Focus/FocusOwnerFrameOnClick \
-java/awt/Focus/FocusSubRequestTest \
-java/awt/Focus/FocusTransitionTest \
-java/awt/Focus/FocusTraversalPolicy \
-java/awt/Focus/FocusTraversalPolicyIAE.java \
-java/awt/Focus/FrameJumpingToMouse \
-java/awt/Focus/FrameMinimizeTest \
-java/awt/Focus/IconifiedFrameFocusChangeTest \
-java/awt/Focus/InitialFocusTest.java \
-java/awt/Focus/InputVerifierTest3 \
-java/awt/Focus/KeyEventForBadFocusOwnerTest \
-java/awt/Focus/LabelScrollBarFocus.java \
-java/awt/Focus/ModalBlockedStealsFocusTest \
-java/awt/Focus/ModalDialogActivationTest \
-java/awt/Focus/ModalDialogInFocusEventTest.java \
-java/awt/Focus/ModalDialogInitialFocusTest \
-java/awt/Focus/ModalExcludedWindowClickTest \
-java/awt/Focus/MouseClickRequestFocusRaceTest \
-java/awt/Focus/NoAutotransferToDisabledCompTest \
-java/awt/Focus/NoFocusOwnerAWTTest.java \
-java/awt/Focus/NoFocusOwnerSwingTest.java \
-java/awt/Focus/NonFocusableBlockedOwnerTest \
-java/awt/Focus/NonFocusableResizableTooSmall \
-java/awt/Focus/NonFocusableWindowTest \
-java/awt/Focus/NullActiveWindowOnFocusLost \
-java/awt/Focus/OwnedWindowFocusIMECrashTest \
-java/awt/Focus/QuickTypeTest.java \
-java/awt/Focus/RemoveAfterRequest \
-java/awt/Focus/RequestFocusAndHideTest \
-java/awt/Focus/RequestFocusByCause \
-java/awt/Focus/RequestFocusToDisabledCompTest \
-java/awt/Focus/RequestOnCompWithNullParent \
-java/awt/Focus/ResetMostRecentFocusOwnerTest \
-java/awt/Focus/RestoreFocusInfiniteLoopTest.java \
-java/awt/Focus/RestoreFocusOnDisabledComponentTest \
-java/awt/Focus/RollbackFocusFromAnotherWindowTest \
-java/awt/Focus/RowToleranceTransitivityTest.java \
-java/awt/Focus/SequencedLightweightRequestsTest.java \
-java/awt/Focus/SetFocusableTest.java \
-java/awt/Focus/ShowFrameCheckForegroundTest \
-java/awt/Focus/SimpleWindowActivationTest \
-java/awt/Focus/SortingFPT \
-java/awt/Focus/TemporaryLostComponentDeadlock.java \
-java/awt/Focus/ToFrontFocusTest \
-java/awt/Focus/TranserFocusToWindow \
-java/awt/Focus/TraversalKeysPropertyNamesTest.java \
-java/awt/Focus/TypeAhead \
-java/awt/Focus/UnaccessibleChoice \
-java/awt/Focus/UpFocusCycleTest.java \
-java/awt/Focus/VetoableChangeListenerLoopTest.java \
-java/awt/Focus/WindowInitialFocusTest \
-java/awt/Focus/WindowIsFocusableAccessByThreadsTest \
-java/awt/Focus/WindowUpdateFocusabilityTest \
-java/awt/Focus/WrongKeyTypedConsumedTest \
-java/awt/font/TextLayout/MyanmarTextTest.java \
-java/awt/font/TextLayout/TestJustification.html \
-java/awt/font/TextLayout/TestOldHangul.java \
-java/awt/font/TextLayout/TestTibetan.java \
-java/awt/font/TextLayout/TestVS.java \
-java/awt/font/TextLayout/VariationSelectorTest.java \
-java/awt/FontClass/FontAccess.java \
-java/awt/Frame \
-java/awt/FullScreen/8013581 \
-java/awt/FullScreen/AllFramesMaximize \
-java/awt/FullScreen/AltTabCrashTest \
-java/awt/FullScreen/BufferStrategyExceptionTest \
-java/awt/FullScreen/FullScreenInsets \
-java/awt/FullScreen/FullscreenWindowProps \
-java/awt/FullScreen/TranslucentWindow \
-java/awt/grab \
-java/awt/Graphics/DrawOvalTest.java \
-java/awt/Graphics/LCDTextAndGraphicsState.java \
-java/awt/Graphics/TextAAHintsTest.java \
-java/awt/Graphics/XORPaint.java \
-java/awt/Graphics2D/CopyAreaOOB.java \
-java/awt/GraphicsDevice/DisplayModes/CompareToXrandrTest.java \
-java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java \
-java/awt/GridBagLayout \
-java/awt/GridLayout \
-java/awt/Gtk \
-java/awt/hidpi \
-java/awt/Icon \
-java/awt/im \
-java/awt/image/BufferStrategy/ExceptionAfterComponentDispose.java \
-java/awt/image/MemoryLeakTest/MemoryLeakTest.java \
-java/awt/image/OpaquePNGToGIFTest.java \
-java/awt/image/VolatileImage/DrawBufImgOp.java \
-java/awt/image/VolatileImage/TransparentVImage.java \
-java/awt/image/mlib/MlibOpsTest.java \
-java/awt/image/multiresolution/MenuMultiresolutionIconTest.java \
-java/awt/image/multiresolution/MultiDisplayTest/MultiDisplayTest.java \
-java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java \
-java/awt/image/multiresolution/MultiresolutionIconTest.java \
-java/awt/Insets/CombinedTestApp1.java \
-java/awt/Insets/RemoveMenuBarTest.java \
-java/awt/InputMethods \
-java/awt/JAWT \
-java/awt/keyboard \
-java/awt/KeyboardFocusmanager/ConsumeNextMnemonicKeyTypedTest \
-java/awt/KeyboardFocusmanager/TypeAhead \
-java/awt/Label \
-java/awt/Layout \
-java/awt/LightweightComponent \
-java/awt/LightweightDispatcher \
-java/awt/List \
-java/awt/Menu \
-java/awt/MenuBar \
-java/awt/MenuItem \
-java/awt/Mixing \
-java/awt/Modal \
-java/awt/Mouse \
-java/awt/MouseAdapter \
-java/awt/MouseInfo \
-java/awt/MultipleGradientPaint \
-java/awt/Multiscreen/MouseEventTest/MouseEventTest.java \
-java/awt/Multiscreen/MultiScreenInsetsTest/MultiScreenInsetsTest.java \
-java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java \
-java/awt/Paint/bug8024864.java \
-java/awt/Paint/ButtonRepaint.java \
-java/awt/Paint/CheckboxRepaint.java \
-java/awt/Paint/ComponentIsNotDrawnAfterRemoveAddTest \
-java/awt/Paint/ExposeOnEDT.java \
-java/awt/Paint/LabelRepaint.java \
-java/awt/Paint/ListRepaint.java \
-java/awt/Paint/PaintNativeOnUpdate.java \
-java/awt/Panel \
-java/awt/PopupMenu \
-java/awt/print \
-java/awt/PrintJob \
-java/awt/Robot \
-java/awt/Scrollbar \
-java/awt/ScrollPane \
-java/awt/security \
-java/awt/SplashScreen \
-java/awt/TextArea \
-java/awt/TextComponent \
-java/awt/TextField \
-java/awt/Toolkit/BadDisplayTest/BadDisplayTest.java \
-java/awt/Toolkit/DesktopProperties/rfe4758438.java \
-java/awt/Toolkit/DynamicLayout/bug7172833.java \
-java/awt/Toolkit/Headless/GetPrintJob/GetPrintJob.java \
-java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh \
-java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java \
-java/awt/Toolkit/RealSync/Test.java \
-java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java \
-java/awt/Toolkit/SecurityTest/SecurityTest2.java \
-java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java \
-java/awt/TrayIcon \
-java/awt/wakefield \
-java/awt/Window \
-java/awt/WMSpecificTests \
-java/awt/xembed

View File

@@ -146,6 +146,7 @@ public class RowToleranceTransitivityTest {
if (!setFocusOn(cb, new Runnable() {
public void run() {
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
}
})) {
System.out.println("Focus got stuck while traversing.");

View File

@@ -182,13 +182,6 @@ public class FontExtensionsTest {
return !textDrawingEquals(BASE_FONT, fontWithFeatures(FontExtensions.FeatureTag.FRAC), FRACTION_STRING);
}
@JBRTest
private static Boolean testFeaturesZeroFrac() {
Font fontFZ = fontWithFeatures(FontExtensions.FeatureTag.FRAC, FontExtensions.FeatureTag.ZERO);
return !textDrawingEquals(fontFZ, fontWithFeatures(FontExtensions.FeatureTag.FRAC), ZERO_STRING + " " + FRACTION_STRING) &&
!textDrawingEquals(fontFZ, fontWithFeatures(FontExtensions.FeatureTag.ZERO), ZERO_STRING + " " + FRACTION_STRING);
}
@JBRTest
private static Boolean testFeaturesDerive1() {
Font fontFZ1 = fontWithFeatures(FontExtensions.FeatureTag.FRAC, FontExtensions.FeatureTag.ZERO).

View File

@@ -0,0 +1,79 @@
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
/*
* @test
* @summary JBR-6060 Verify that the focus traverse to the next component if the current focused became invisible
* @run main/othervm FocusTraversalOrderTest
*/
public class FocusTraversalOrderTest {
private static Frame frame;
private static Button button0, button1, button2, button3, button4;
public static void main(String... args) throws InterruptedException, InvocationTargetException, AWTException {
Robot robot = new Robot();
try {
EventQueue.invokeAndWait(() -> {
frame = new Frame();
frame.setLayout(new FlowLayout());
frame.setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy());
button0 = new Button();
button0.setFocusable(true);
frame.add(button0);
button1 = new Button();
button1.setFocusable(true);
frame.add(button1);
button2 = new Button();
button2.setFocusable(true);
frame.add(button2);
button3 = new Button();
button3.setFocusable(true);
frame.add(button3);
button4 = new Button();
button4.setFocusable(true);
frame.add(button4);
frame.pack();
frame.setVisible(true);
});
frame.requestFocus();
frame.toFront();
robot.waitForIdle();
button2.requestFocusInWindow();
robot.waitForIdle();
button2.setVisible(false);
robot.waitForIdle();
boolean isRightFocus = button3.isFocusOwner();
if (!isRightFocus) {
System.out.println("ERROR: button3 expected to be focus owner");
}
FocusTraversalPolicy focusTraversalPolicy = frame.getFocusTraversalPolicy();
Component compAfterButton2 = focusTraversalPolicy.getComponentAfter(frame, button2);
boolean isRightNextComp = compAfterButton2.equals(button3);
if (!isRightNextComp) {
System.out.println("ERROR: the next component after button2 expected to be button3, but got " + compAfterButton2.getName());
}
if (!(isRightFocus && isRightNextComp)) {
throw new RuntimeException("TEST FAILED: the next component didn't gain the focus");
} else {
System.out.println("TEST PASSED");
}
} finally {
EventQueue.invokeAndWait(() -> {
if (frame != null) {
frame.dispose();
}
});
}
}
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary A manual test of JBR-5984 bug checks if an IM's window is placed above Swing's/AWT's popups
* @author Nikita Provotorov
* @requires (os.family == "mac")
* @key headful
* @run main/othervm/manual -Xcheck:jni ImWindowIsPlacedUnderPopup5984
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class ImWindowIsPlacedUnderPopup5984 extends JFrame {
static final CompletableFuture<RuntimeException> swingError = new CompletableFuture<>();
public static void main(String[] args) throws InterruptedException, InvocationTargetException, ExecutionException {
final ImWindowIsPlacedUnderPopup5984 frame;
{
final CompletableFuture<ImWindowIsPlacedUnderPopup5984> frameFuture = new CompletableFuture<>();
SwingUtilities.invokeAndWait(() -> {
try {
final var result = new ImWindowIsPlacedUnderPopup5984();
result.setVisible(true);
frameFuture.complete(result);
} catch (Throwable err) {
frameFuture.completeExceptionally(err);
}
});
frame = frameFuture.get();
}
try {
final var err = swingError.get();
if (err != null) {
throw err;
}
} finally {
if (frame != null) {
SwingUtilities.invokeAndWait(frame::dispose);
}
}
}
public ImWindowIsPlacedUnderPopup5984() {
super("JBR-5984");
setDefaultCloseOperation(HIDE_ON_CLOSE);
popupShowingButton = new JButton("Show a Popup");
add(popupShowingButton, BorderLayout.NORTH);
instructionTextArea = new JTextArea();
instructionTextArea.setLineWrap(true);
instructionTextArea.setWrapStyleWord(true);
instructionTextArea.setText(
"""
INSTRUCTION:
1. Switch the input source to an input method (e.g. "Pinyin - Simplified");
2. Press the "Show a Popup" button;
3. Start typing into the text field on the shown popup;
4. Check if the input candidates' popup is shown above the java popup:
4.1. If it's shown above, press the "PASS" button;
4.2. Otherwise, press the "FAIL" button.
"""
);
instructionTextArea.setEditable(false);
add(instructionTextArea, BorderLayout.CENTER);
final JPanel southContainer = new JPanel(new BorderLayout());
failTestButton = new JButton("FAIL");
passTestButton = new JButton("PASS");
southContainer.add(failTestButton, BorderLayout.LINE_START);
southContainer.add(passTestButton, BorderLayout.LINE_END);
add(southContainer, BorderLayout.SOUTH);
popupPanel = new JPanel();
popupTextField = new JTextArea();
popupTextField.setPreferredSize(new Dimension(200, 125));
popupPanel.add(popupTextField);
pack();
setSize(400, 250);
setLocationRelativeTo(null);
popup = new JPopupMenu();
popup.add(popupPanel);
popup.pack();
popupShowingButton.addActionListener(ignored -> popup.show(ImWindowIsPlacedUnderPopup5984.this, 100, 65));
failTestButton.addActionListener(ignored -> swingError.completeExceptionally(new RuntimeException("The tester has pressed FAILED")));
passTestButton.addActionListener(ignored -> swingError.complete(null));
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
swingError.completeExceptionally(new RuntimeException("The window was closed not through the \"PASS\"/\"FAIL\" buttons"));
}
});
}
private final JButton popupShowingButton;
private final JTextArea instructionTextArea;
private final JButton failTestButton;
private final JButton passTestButton;
private final JPanel popupPanel;
private final JTextArea popupTextField;
private final JPopupMenu popup;
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.CountDownLatch;
/*
* @test
* @summary Verifies that the program finishes after disposing of JFrame
* @run main WLShutdownTest
*/
public class WLShutdownTest {
private static JFrame frame = null;
public static void main(String[] args) throws Exception {
final CountDownLatch latchShownFrame = new CountDownLatch(1);
final CountDownLatch latchClosedFrame = new CountDownLatch(1);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
frame = new JFrame("TEST");
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
latchShownFrame.countDown();
}
});
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latchClosedFrame.countDown();
}
});
JPanel panel = new JPanel() {
int n = 0;
@Override
protected void paintComponent(Graphics g) {
System.out.print("P");
g.setColor((n++ % 2 == 0) ? Color.RED : Color.BLUE);
g.fillRect(0, 0, getWidth(), getHeight());
System.out.print("Q");
}
};
panel.setPreferredSize(new Dimension(800, 800));
panel.setBackground(Color.BLACK);
frame.add(panel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.print(">>");
}
});
// Wait frame to be shown:
latchShownFrame.await();
System.out.print(":>>");
final long startTime = System.currentTimeMillis();
final long endTime = startTime + 3000;
// Start 1st measurement:
repaint();
for (; ; ) {
System.out.print(".");
repaint();
if (System.currentTimeMillis() >= endTime) {
break;
}
sleep();
} // end measurements
SwingUtilities.invokeAndWait(() -> {
frame.setVisible(false);
frame.dispose();
});
latchClosedFrame.await();
System.out.print("<<\n");
frame = null; // free static ref: gc
System.out.println("Waiting AWT to shutdown JVM soon ...");
}
static void repaint() throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
frame.repaint();
}
});
}
static void sleep() {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
ie.printStackTrace(System.err);
}
}
}

View File

@@ -29,6 +29,8 @@
* @requires (jdk.version.major >= 8 & os.family == "mac")
*/
import sun.lwawt.macosx.LWCToolkit;
import static java.awt.event.KeyEvent.*;
public class KeyCodesTest implements Runnable {
@@ -140,6 +142,10 @@ public class KeyCodesTest implements Runnable {
}
private void verify(String typed, int vk, String layout, int key, int charKeyCode, int location, int modifiers) {
if (!LWCToolkit.isKeyboardLayoutInstalled(layout)) {
System.out.printf("WARNING: Skipping key code test, vk = %d, layout = %s: this layout is not installed", vk, layout);
return;
}
char ch = (typed.length() == 1) ? typed.charAt(0) : 0;
InputMethodTest.section("Key code test: " + vk + ", layout: " + layout + ", char: " + String.format("U+%04X", (int)ch));
InputMethodTest.layout(layout);

View File

@@ -1,6 +1,48 @@
java/awt/Choice/ChoicePopupLocation/ChoicePopupLocation.java 8202931,JBR-5398 macosx-all,linux-all,windows-all
java/awt/Debug/X11Trace.java JBR-5442 linux-all
java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java JBR-6058 windows-all
java/awt/FullScreen/CurrentDisplayModeTest/CurrentDisplayModeTest.java JBR-5059 linux-all
java/awt/FullScreen/MultimonFullscreenTest/MultimonDeadlockTest.java JBR-4379 windows-all
java/awt/Frame/FramesGC/FramesGC.java JBR-6057 windows-all
java/awt/GraphicsDevice/DisplayModes/CompareToXrandrTest.java JBR-5062 linux-all
java/awt/datatransfer/Clipboard/GetContentsInterruptedTest.java JBR-5086 linux-5.15.0-46-generic Ubuntu 20.04
java/awt/dnd/MissedDragEnterTest.java JBR-6091 windows-all
java/awt/Frame/FramesGC/FramesGC.java JBR-6057 windows-all
java/awt/Frame/GetGraphicsStressTest/GetGraphicsStressTest.java JBR-5117 linux-all
java/awt/LightweightDispatcher/LWDispatcherMemoryLeakTest.java 8311535 windows-all
java/awt/Multiscreen/WindowGCChangeTest/WindowGCChangeTest.java JBR-5531 macosx-all
java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java#id1 JBR-5442 linux-all
java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java 8253184,JBR-5442 windows-all,linux-all
java/awt/MouseInfo/MultiscreenPointerInfo.java JBR-5442 linux-all
java/awt/Multiscreen/LocationRelativeToTest/LocationRelativeToTest.java 8253184,JBR-5442 windows-all,linux-all
java/awt/Multiscreen/MultiScreenLocationTest/MultiScreenLocationTest.java JBR-5442 linux-all
java/awt/Multiscreen/WindowGCChangeTest/WindowGCChangeTest.java JBR-5531,JBR-5442 macosx-all,linux-all
java/awt/Multiscreen/UpdateGCTest/UpdateGCTest.java JBR-5442 linux-all
java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-5442 windows-all,linux-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510,JBR-5442,JBR-6092 windows-all,linux-all,macosx-aarch64
java/awt/Robot/CheckCommonColors/CheckCommonColors.java JBR-6092 macosx-aarch64
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184,JBR-5442 windows-all,linux-all
java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java JBR-5390 macosx-all,linux-all
java/awt/Robot/NonEmptyErrorStream.java JBR-5442 linux-all
java/awt/Robot/RobotMoveMultiscreen.java JBR-5442 linux-all
java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java JBR-6065 windows-all
java/awt/Window/SlowMotion/SlowMotion.java JBR-5442 linux-all
java/awt/Window/WindowSizeDifferentScreens/WindowSizeDifferentScreens.java JBR-5442 linux-all
java/awt/dnd/MissingEventsOnModalDialog/MissingEventsOnModalDialogTest.java JBR-5442 linux-all
java/awt/im/memoryleak/InputContextMemoryLeakTest.java JBR-6065 windows-all
java/awt/image/VolatileImage/DrawHugeImageTest.java JBR-5442 linux-all
javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java JBR-5442 linux-all
javax/swing/JComboBox/TestComboBoxComponentRendering.java JBR-6100 linux-all
javax/swing/JInternalFrame/Test6325652.java JBR-6065 windows-all
javax/swing/JMenu/4692443/bug4692443.java JBR-6065 windows-all
javax/swing/JMenuBar/4750590/bug4750590.java JBR-6065 windows-all
javax/swing/JMenuItem/4171437/bug4171437.java JBR-6065 windows-all
javax/swing/JTable/7124218/SelectEditTableCell.java JBR-5442 linux-all
javax/swing/JTextArea/8149849/DNDTextToScaledArea.java 8253184 windows-all
javax/swing/JTextField/8036819/bug8036819.java JBR-6065 windows-all
javax/swing/JTree/4927934/bug4927934.java JBR-6065 windows-all
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-5442 linux-all
javax/swing/plaf/metal/MetalGradient/8163193/ButtonGradientTest.java 8253184,JBR-5510,JBR-5442 windows-all,linux-all
javax/swing/SwingWorker/TestDoneBeforeDoInBackground.java JBR-5442 linux-all
javax/swing/text/html/StyleSheet/bug4936917.java JBR-899,JBR-5510,JBR-5442 windows-all,linux-all
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,JBR-5442 windows-x64,linux-all

View File

@@ -142,6 +142,7 @@ java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java 820420
java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java 8204200 windows-all,macosx-all,linux-all
java/awt/dnd/DropTargetEnterExitTest/ExtraDragEnterTest.java 8029680 generic-all
java/awt/dnd/DropTargetEnterExitTest/MissedDragExitTest.java JBR-5730 linux-all
java/awt/dnd/NextDropActionTest/NextDropActionTest.java 8313633 macosx-aarch64
java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java 8288839,JBR-5727,JBR-5959 windows-x64,linux-all, windows-aarch64
java/awt/dnd/URIListBetweenJVMsTest/URIListBetweenJVMsTest.java 8171510,JBR-881 macosx-all,linux-all
javax/swing/dnd/7171812/bug7171812.java 8041447,8253184 macosx-all,windows-all
@@ -343,9 +344,9 @@ java/awt/Clipboard/HTMLTransferTest/HTMLTransferTest.java 8017454 macosx-all
java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/ActiveSwingWindowTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,linux-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,generic-all
java/awt/Robot/HiDPIMouseClick/HiDPIRobotMouseClick.java 8253184 windows-all
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184,JBR-5827 macosx-all,windows-all,linux-all
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184 macosx-all,windows-all
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009,8253184 macosx-all,windows-all
java/awt/Modal/FileDialog/FileDialogAppModal3Test.java 7186009,8253184 macosx-all,windows-all
java/awt/Modal/FileDialog/FileDialogAppModal4Test.java 7186009,8253184 macosx-all,windows-all
@@ -633,6 +634,7 @@ java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java 8253184 windows-all
java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Enable.java 6847163 linux-all
java/awt/xembed/server/RunTestXEmbed.java 7034201 linux-all
java/awt/Modal/ModalFocusTransferTests/FocusTransferDialogsDocModalTest.java 8164473 linux-all
java/awt/Frame/DecoratedFrameInsets/DecoratedFrameInsetsTest.java JBR-5205 linux-5.4.0-1103-aws
java/awt/Frame/DisposeParentGC/DisposeParentGC.java 8079786 macosx-all
java/awt/GraphicsDevice/CheckDisplayModes.java 8266242 macosx-aarch64
@@ -662,6 +664,7 @@ java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java 8238720 w
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720 windows-all
java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720 windows-all
java/awt/wakefield/RobotKeyboard.java JBR-5653 linux-all
java/awt/wakefield/ScreenCapture.java JBR-5653 linux-all
# Several tests which fail sometimes on macos11
@@ -874,12 +877,13 @@ javax/imageio/plugins/external_plugin_tests/TestClassPathPlugin.sh JBR-5363 wind
javax/swing/plaf/basic/BasicComboPopup/JComboBoxPopupLocation/JComboBoxPopupLocation.java 8194945 macosx-all
javax/swing/plaf/basic/BasicHTML/4251579/bug4251579.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java 8253184 windows-all
javax/swing/plaf/basic/BasicTableHeaderUI/6394566/bug6394566.java JBR-5846 windows-all
javax/swing/plaf/basic/BasicTextUI/8001470/bug8001470.java 8233177 linux-all,windows-all
javax/swing/plaf/basic/BasicTreeUI/8023474/bug8023474.java 8253184 linux-all,windows-all
javax/swing/plaf/nimbus/8041642/bug8041642.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/nimbus/8057791/bug8057791.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/plaf/nimbus/TestNimbusBGColor.java JBR-5359 windows-aarch64
javax/swing/plaf/nimbus/TestNimbusOverride.java 8253184 windows-all
javax/swing/plaf/nimbus/TestNimbusOverride.java 8253184, JBR-5829 windows-all,linux-all
javax/swing/plaf/windows/6921687/bug6921687.java 8253184 windows-all
javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java JBR-4372 windows-all
@@ -894,14 +898,21 @@ javax/swing/JColorChooser/Test6524757.java JBR-5210 windows-all
javax/swing/JColorChooser/Test6827032.java JBR-5210 windows-all
javax/swing/JComboBox/6406264/bug6406264.java JBR-5210 windows-all
javax/swing/JComboBox/bug4890345.java JBR-5799 windows-all
javax/swing/JComboBox/bug4924758.java JBR-5846 windows-all
javax/swing/JComboBox/bug5029504.java JBR-5799 windows-all
javax/swing/JComponent/6683775/bug6683775.java 8172337 generic-all
javax/swing/JDialog/Transparency/TransparencyTest.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
javax/swing/JLabel/4138746/JLabelMnemonicsTest.java JBR-4949 linux-all,windows-all
javax/swing/JLabel/6596966/bug6596966.java 8197552 windows-all
javax/swing/JLabel/7004134/bug7004134.java JBR-5437 linux-all
javax/swing/JMenu/4213634/bug4213634.java 8197552 windows-all
javax/swing/JMenu/4515762/bug4515762.java 8197552 windows-all
javax/swing/JMenu/4692443/bug4692443.java JBR-6093 windows-x64
javax/swing/JMenu/6470128/bug6470128.java 8253184 windows-all
javax/swing/JMenu/6538132/bug6538132.java JBR-894 windows-all00
javax/swing/JMenu/PopupReferenceMemoryLeak.java JBR-5890,JBR-6056 windows-aarch64,windows-x64
javax/swing/JMenuBar/4750590/bug4750590.java JBR-6094 windows-x64
javax/swing/JMenuItem/4171437/bug4171437.java JBR-6112 windows-x64
javax/swing/JMenuItem/4654927/bug4654927.java JBR-164 windows-all
javax/swing/JMenuItem/4654927/bug4654927.java JBR-164,JBR-4337 windows-all,linux-all
javax/swing/JMenuItem/6209975/bug6209975.java 8253184 windows-all
@@ -944,6 +955,7 @@ javax/swing/JEditorPane/bug4714674.java JBR-5810 windows-all
javax/swing/JComboBox/DisabledComboBoxFontTestAuto.java 8310072 linux-all,windows-all
javax/swing/JEditorPane/JEditorPaneGCSwitchTest/JEditorPaneGCSwitchTest_i18n.java JBR-912 windows-all
javax/swing/JEditorPane/JEditorPaneGCSwitchTest/JEditorPaneGCSwitchTest.java JBR-912 windows-all
javax/swing/JFileChooser/4524490/bug4524490.java JBR-5846 windows-all
javax/swing/JFileChooser/8021253/bug8021253.java JBR-107 windows-all
javax/swing/JFileChooser/8041694/bug8041694.java JBR-5210 windows-all
javax/swing/JFileChooser/6396844/TwentyThousandTest.java 8198003 generic-all
@@ -951,7 +963,7 @@ javax/swing/JFileChooser/6520101/bug6520101.java JBR-5703 linux-5.8.0-1032-raspi
javax/swing/JFileChooser/6570445/bug6570445.java JBR-5767 windows-all
javax/swing/JFileChooser/6738668/bug6738668.java JBR-5767 windows-all
javax/swing/JFileChooser/7036025/bug7036025.java JBR-5767 windows-all
javax/swing/JFileChooser/8062561/bug8062561.java JBR-5767 windows-all
javax/swing/JFileChooser/8062561/bug8062561.java JBR-5767,JBR-5808 windows-all
javax/swing/JFileChooser/8194044/FileSystemRootTest.java JBR-5767 windows-all
javax/swing/JFileChooser/ShellFolderQueries/ShellFolderQueriesSecurityManagerTest.java JBR-5767 windows-all
javax/swing/JFrame/8016356/bug8016356.java JBR-108 windows-all
@@ -964,9 +976,11 @@ javax/swing/JTabbedPane/4361477/bug4361477.java JBR-5932 linux-all
javax/swing/JTabbedPane/8007563/Test8007563.java 8051591 generic-all
javax/swing/JTabbedPane/4624207/bug4624207.java 8064922,8197552 macosx-all,windows-all 8064922:macosx-all, 8197552:windows-all
javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 8253184,windows-all
javax/swing/JToggleButton/TestSelectedKey.java JBR-5846 windows-all
javax/swing/JToolBar/4529206/bug4529206.java JBR-5387 linux-all
javax/swing/JToolTip/6219960/bug6219960.java 8253184 windows-all
javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all
javax/swing/text/AbstractDocument/8190763/TestCCEOnEditEvent.java JBR-5799 windows-all
javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/text/TableView/TableViewLayoutTest.java 8194936,JBR-4316,JBR-5510 linux-5.18.2-arch1-1,linux-all
javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all
@@ -977,6 +991,7 @@ javax/swing/JInternalFrame/6288609/TestJInternalFrameDispose.java JBR-788 window
javax/swing/JInternalFrame/6647340/bug6647340.java 8253184 windows-all
javax/swing/JInternalFrame/8145060/TestJInternalFrameMinimize.java JBR-788 windows-all,linux-all
javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java JBR-5539 windows-all
javax/swing/JInternalFrame/Test6325652.java JBR-6111 windows-all
javax/swing/JInternalFrame/Test6505027.java JBR-5954 linux-all,osx-all
javax/swing/JInternalFrame/Test6802868.java 8253184 windows-all
javax/swing/JPopupMenu/4634626/bug4634626.java 8253184 windows-all
@@ -1002,6 +1017,7 @@ javax/swing/JInternalFrame/5066752/bug5066752.java 8253184,JBR-5510 windows-all,
javax/swing/JInternalFrame/8160248/JInternalFrameDraggingTest.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
javax/swing/JInternalFrame/8020708/bug8020708.java JBR-4879 windows-all
javax/swing/JInternalFrame/8069348/bug8069348.java 8253184,JBR-900 macosx-aarch64,windows-all
javax/swing/ToolTipManager/Test6256140.java 8197552 windows-all
javax/swing/text/DefaultEditorKit/4278839/bug4278839.java CODETOOLS-7901623 windows-all
javax/swing/text/GlyphPainter2/6427244/bug6427244.java JBR-896 windows-all
javax/swing/text/JTextComponent/5074573/bug5074573.java CODETOOLS-7901623,JBR-5386 windows-all,linux-all
@@ -1010,7 +1026,7 @@ javax/swing/text/StyledEditorKit/4506788/bug4506788.java JBR-180 windows-all
javax/swing/text/View/8014863/bug8014863.java JBR-5541 windows-all
javax/swing/text/View/8156217/FPMethodCalledTest.java JBR-5541 linux-all
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952 windows-x64
javax/swing/UIDefaults/6795356/TableTest.java.TableTest JBR-5767 windows-all
javax/swing/UIDefaults/6795356/TableTest.java JBR-5767 windows-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8253184 windows-all
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java 8253184 windows-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
@@ -1023,7 +1039,8 @@ sanity/client/SwingSet/src/DialogDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/FrameDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/InternalFrameDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/TextFieldDemoTest.java JBR-5061 linux-5.15.0-39-generic Ubuntu-22.04
sanity/client/SwingSet/src/TextFieldDemoTest.java JBR-5061 linux-all Ubuntu-22.04
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001 linux-all
sanity/client/SwingSet/src/SliderDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/SpinnerDemoTest.java 8253184 windows-all
sanity/client/SwingSet/src/SplitPaneDemoTest.java JBR-5817 linux-5.19.0-1025-aws
@@ -1154,6 +1171,8 @@ java/awt/font/EmojiVariation.java JBR-5009,JBR-5510 linux-aarch64,linux-5.18.2-a
java/awt/font/TextLayout/TestJustification.html 8250791 macosx-all
java/awt/font/TextLayout/TestSinhalaChar.java JBR-5103 generic-all
javax/swing/JTableHeader/6889007/bug6889007.java 8310238,8253184,JBR-5387 macosx-all,windows-all,linux-all
javax/swing/JTextField/8036819/bug8036819.java JBR-6113 windows-x64
javax/swing/JTree/4927934/bug4927934.java JBR-6114 windows-x64
java/awt/TrayIcon/DragEventSource/DragEventSource.java 8252242 macosx-all
java/awt/FileDialog/DefaultFocusOwner/DefaultFocusOwner.java 7187728 macosx-all,linux-all
java/awt/FileDialog/RegexpFilterTest/RegexpFilterTest.html 7187728 macosx-all,linux-all
@@ -1166,6 +1185,7 @@ java/awt/TextArea/TextAreaTwicePack/TextAreaTwicePack.java 8253184 windows-all
java/awt/TextField/OverScrollTest/OverScrollTest.java 8253184 windows-all
java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macosx-all
java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289,JBR-5359 windows-x64,windows-aarch64
java/awt/Focus/RemoveAfterRequest/RemoveAfterRequest.java JBR-6052 macosx-all,linux-all
java/awt/Focus/RowToleranceTransitivityTest.java JBR-5751 windows-all
java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103,8253184 linux-all,windows-all
@@ -1222,6 +1242,7 @@ com/sun/java/swing/plaf/windows/AltFocusIssueTest.java
java/awt/event/MouseEvent/AltGraphModifierTest/AltGraphModifierTest.java JBR-4207 windows-all
jb/java/awt/Graphics2D/TextRender/OGLMetalTextRender.java JBR-5392 windows-aarch64
jb/java/awt/event/TouchScreenEvent/TouchScreenEventsTestLinux.sh JBR-4078 linux-all
jb/java/awt/event/MouseEvent/ReleaseAndClickModifiers.java JBR-5366 windows-all
jb/java/awt/Font/Font467.java JBR-3960 generic-all
jb/java/awt/keyboard/AltGrMustGenerateAltGrModifierTest4207.java JBR-4207 windows-all
jb/java/awt/Toolkit/AWTThreadingTest.java JBR-4350 macosx-all
@@ -1258,6 +1279,7 @@ javax/swing/JSpinner/JSpinnerFocusTest.java JBR-5288 windows-all
javax/swing/JSpinner/SpinnerTest.java JBR-4880 windows-all
javax/swing/JSpinner/TestJSpinnerFocusLost.java JBR-5210 windows-all
javax/swing/JTable/7068740/bug7068740.java 8197552 windows-all
javax/swing/JTable/8236907/LastVisibleRow.java JBR-6066 macosx-aarch64
javax/swing/text/FlowView/LayoutTest.java JBR-4880 windows-all
javax/swing/text/html/7189299/bug7189299.java JBR-4880 windows-all
jb/java/jcef/HandleJSQueryTest3314.sh JBR-4866 linux-all
@@ -1319,6 +1341,7 @@ javax/sound/sampled/Mixers/BogusMixers.java JBR-4455 linux-aarch64
java/awt/Choice/RemoveAllShrinkTest/RemoveAllShrinkTest.java JBR-5359,JBR-5510,8310487 windows-aarch64,linux-5.18.2-arch1-1,linux-all
java/awt/Choice/ResizeAutoClosesChoice/ResizeAutoClosesChoice.java JBR-5359,JBR-5510,JBR-5905 windows-aarch64,linux-5.18.2-arch1-1,linux-all
java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java 8315733 macosx-all
java/awt/ColorClass/XRenderTranslucentColorDrawTest.java JBR-5359 windows-aarch64
java/awt/Frame/InvisibleOwner/InvisibleOwner.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Graphics/CopyScaledArea/CopyScaledAreaTest.java JBR-5359 windows-aarch64
@@ -1344,6 +1367,7 @@ java/awt/image/VolatileImage/ReportRenderingError.java#windows JBR-5359 windows-
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
java/awt/Mixing/LWPopupMenu.java JBR-824 generic-all
java/awt/Mixing/OpaqueTest.java JBR-5707 linux-all
java/awt/Mixing/OverlappingButtons.java JBR-5707 linux-all
java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
@@ -1366,24 +1390,26 @@ jb/java/awt/CustomTitleBar/HitTestNonClientArea.java JBR-5465,JBR-5550 windows-a
jb/java/awt/CustomTitleBar/MaximizeWindowTest.java JBR-5465,JBR-5550 windows-all
jb/java/awt/CustomTitleBar/MaximizedWindowFocusTest.java JBR-5828 windows-all
jb/java/awt/CustomTitleBar/MinimizingWindowTest.java JBR-5359,JBR-5345 windows-aarch64,windows-x64
jb/java/awt/CustomTitleBar/MouseEventsOnClientArea.java JBR-5910 windows-x64
jb/java/awt/CustomTitleBar/NativeControlsVisibilityTest.java JBR-5359,JBR-5345 windows-aarch64,windows-x64
jb/java/awt/CustomTitleBar/WindowsControlWidthTest.java JBR-5359,JBR-5345 windows-aarch64,windows-x64
jb/java/awt/CustomTitleBar/WindowResizeTest.java JBR-5592 windows-all
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
sun/java2d/AcceleratedXORModeTest.java JBR-5359 windows-aarch64
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
sun/java2d/GdiRendering/InsetClipping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5359,JBR-5366,JBR-5510 windows-all,linux-5.18.2-arch1-1
sun/java2d/GdiRendering/InsetClipping.java 7124403,JBR-5359,JBR-5366,JBR-5510 windows-all,macosx-all,windows-aarch64,linux-5.18.2-arch1-1
java/awt/Choice/PopdownGeneratesMouseEvents/PopdownGeneratesMouseEvents.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Insets/DialogInsets.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Menu/OpensWithNoGrab/OpensWithNoGrab.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JFormattedTextField/TestSelectedTextBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JMenu/JMenuSelectedColorTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JSpinner/4788637/bug4788637.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/LookAndFeel/8145547/DemandGTK2.sh JBR-5510 linux-5.18.2-arch1-1
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-5510 linux-5.18.2-arch1-1
java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java JBR-5765 macosx-all
jb/sun/awt/macos/InputMethodTest/FocusMoveUncommitedCharactersTest.java JBR-5765 macosx-all
jb/sun/awt/macos/InputMethodTest/FocusMoveUncommitedCharactersTest.java JBR-5765 macosx-all
jb/java/awt/Focus/FocusTraversalOrderTest.java JBR-6060 generic-all

View File

@@ -1,16 +1,47 @@
java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.java JBR-5538 windows-all
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java JBR-4199 linux-5.4.0-1083-aws
java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java JBR-4199 linux-5.4.0-1083-aws
java/awt/Dialog/DialogLocationTest.java JBR-6090 windows-all
java/awt/datatransfer/DragUnicodeBetweenJVMTest/DragUnicodeBetweenJVMTest.java JBR-5538 windows-all
java/awt/datatransfer/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java JBR-6027 windows-all
java/awt/dnd/MissedDragEnterTest.java JBR-6091 windows-all
java/awt/event/StressTest/MouseAndKeyEventStressTest.java JBR-6090 windows-all
java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsoluteCoordsTest.java 8238720,JBR-6095 windows-all,linux-all
java/awt/Focus/6378278/InputVerifierTest.java JBR-6090 windows-all
java/awt/Focus/6382144/EndlessLoopTest.java JBR-6090 windows-all
java/awt/Focus/8282640/ScrollPaneFocusBugTest.java JBR-6090 windows-all
java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java JBR-6090 windows-all
java/awt/Focus/LabelScrollBarFocus.java JBR-6090 windows-x64
java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java JBR-6090 windows-x64
java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java JBR-6090 windows-x64
java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java JBR-6089 windows-all
java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java JBR-6090 windows-all
java/awt/Frame/InvisibleOwner/InvisibleOwner.java JBR-6090 windows-all
java/awt/Frame/MaximizedToOppositeScreen/MaximizedToOppositeScreenSmall.java JBR-6090 windows-all
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
java/awt/Frame/SetMaximizedBounds/SetMaximizedBounds.java JBR-6090 windows-all
java/awt/Frame/WindowDragTest/WindowDragTest.java JBR-6090 windows-x64
java/awt/GridLayout/ChangeGridSize/ChangeGridSize.java 8238720,JBR-4199,JBR-6090 linux-5.4.0-1083-aws,linux-5.4.0-1103-aws,windows-all
java/awt/GridLayout/ComponentPreferredSize/ComponentPreferredSize.java JBR-4199,JBR-6090 linux-5.4.0-1083-aws,linux-5.4.0-1103-aws,windows-all
java/awt/Graphics/LineClipTest.java JBR-5071 linux-all
java/awt/image/VolatileImage/DrawHugeImageTest.java JBR-5071 linux-all
java/awt/image/VolatileImage/DrawHugeImageTest.java JBR-5071,JBR-5359 linux-all,windows-aarch64
java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java JBR-5071 linux-all
java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405,JBR-5359,JBR-5510,JBR-6090 macosx-all,windows-aarch64,linux-5.18.2-arch1-1,windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5359,JBR-5510,JBR-6090 windows-aarch64,linux-5.18.2-arch1-1,windows-all
java/awt/Mixing/MixingOnDialog.java JBR-6090 windows-all
java/awt/Modal/BlockedMouseInputTest2.java JBR-6090 windows-all
java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-5071 windows-all,macosx-all,linux-all
javax/swing/JComboBox/TestComboBoxComponentRendering.java JBR-6100 linux-all
javax/swing/JComponent/7154030/bug7154030.java JBR-6134 windows-x64
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-all
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedPerPixelTranslucentGradient.java JBR-6090 windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/ShapedTranslucentPerPixelTranslucentGradient.java JBR-6090 windows-all
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5204 linux-all,windows-all
jb/java/awt/Focus/RequestFocusInParent.java JBR-5715 windows-all
jb/java/awt/Focus/SecondLevelPopupTest.java JBR-6090 windows-all
java/awt/Window/WindowSizeDifferentScreens/WindowSizeDifferentScreens.java JBR-5513 linux-all
jb/java/awt/Window/UndecoratedDialogInTransientsChain.java JBR-6090 windows-all
java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java JBR-6089 windows-all
java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java JBR-6089 windows-all
jb/java/awt/Window/ZOrderOnModalDialogActivation.java JBR-5713 windows-all
jdk/editpad/EditPadTest.java JBR-5712 windows-all

View File

@@ -20,13 +20,9 @@ java/awt/KeyboardFocusmanager/TypeAhead/FreezeTest/FreezeTest.java nobug windows
java/awt/KeyboardFocusmanager/TypeAhead/TestDialogTypeAhead.java nobug windows-all
java/awt/MenuBar/SeparatorsNavigation/SeparatorsNavigation.java nobug windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java nobug windows-all
java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java nobug windows-all
java/awt/Mouse/ExtraMouseClick/ExtraMouseClick.java JBR-4354 windows-all,linux-all # linux: JBR-4354
java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java nobug windows-all
java/awt/Paint/PaintNativeOnUpdate.java nobug windows-all
java/awt/Robot/CheckCommonColors/CheckCommonColors.java nobug windows-all
java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java nobug windows-all
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureTest.java nobug windows-all
java/awt/TextArea/OverScrollTest/OverScrollTest.java nobug windows-all
java/awt/TextField/OverScrollTest/OverScrollTest.java nobug windows-all
java/awt/Window/8159168/SetShapeTest.java nobug windows-all
@@ -52,15 +48,10 @@ javax/swing/JInternalFrame/5066752/bug5066752.java nobug windows-all
javax/swing/JInternalFrame/8145060/TestJInternalFrameMinimize.java nobug windows-all,linux-all
javax/swing/JInternalFrame/Test6505027.java nobug windows-all
javax/swing/JLabel/7004134/bug7004134.java nobug linux-all
javax/swing/JMenu/4213634/bug4213634.java nobug windows-all
javax/swing/JMenu/4692443/bug4692443.java nobug windows-all
javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java nobug windows-all,linux-all
javax/swing/JMenuBar/4750590/bug4750590.java nobug windows-all
javax/swing/JMenuItem/4171437/bug4171437.java nobug windows-all
javax/swing/JMenuItem/4654927/bug4654927.java nobug windows-all,linux-all
javax/swing/JMenuItem/6209975/bug6209975.java JBR-4894 windows-all
javax/swing/JMenuItem/6249972/bug6249972.java JBR-4894 windows-all
javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java nobug windows-all,linux-all
javax/swing/JPopupMenu/4634626/bug4634626.java nobug windows-all
javax/swing/JPopupMenu/4760494/bug4760494.java JBR-4894 windows-all
javax/swing/JPopupMenu/6415145/bug6415145.java nobug windows-all
@@ -79,12 +70,9 @@ javax/swing/JSpinner/TestJSpinnerFocusLost.java nobug windows-all
javax/swing/JTabbedPane/4624207/bug4624207.java 8064922,8197552 macosx-all,windows-all,linux-all 8064922:macosx-all, 8197552:windows-all
javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java nobug windows-all
javax/swing/JTable/7124218/SelectEditTableCell.java JBR-4894 windows-all
javax/swing/JTextArea/8149849/DNDTextToScaledArea.java nobug windows-all
javax/swing/JTextField/8036819/bug8036819.java nobug windows-all
javax/swing/JToolTip/4846413/bug4846413.java nobug windows-all
javax/swing/JToolTip/6219960/bug6219960.java nobug windows-all
javax/swing/JTree/4633594/JTreeFocusTest.java 8173125 macosx-all,windows-all
javax/swing/JTree/4927934/bug4927934.java nobug windows-all
javax/swing/JTree/DnD/LastNodeLowerHalfDrop.java 8159131 linux-all,windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentSwing.java 8194128 macosx-all,windows-all
javax/swing/JWindow/ShapedAndTranslucentWindows/SetShapeAndClickSwing.java 8013450 macosx-all,windows-all
@@ -101,4 +89,3 @@ javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java nobug windows-all
javax/swing/text/JTextComponent/6361367/bug6361367.java nobug windows-all
javax/swing/text/View/8014863/bug8014863.java nobug windows-all
javax/swing/text/View/8156217/FPMethodCalledTest.java nobug linux-all
javax/swing/ToolTipManager/Test6256140.java nobug windows-all

View File

@@ -30,11 +30,13 @@ import quality.util.RenderUtil;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Map;
public class TextMetricsTest {
@@ -42,7 +44,6 @@ public class TextMetricsTest {
public void testTextBounds() throws Exception {
final Font font = new Font("Menlo", Font.PLAIN, 22);
BufferedImage bi = RenderUtil.capture(120, 120,
g2 -> {
String s = "A";
@@ -92,4 +93,49 @@ public class TextMetricsTest {
Assert.assertTrue(bnd.getX() == 0.0 && bnd.getY() == 0.0 &&
bnd.getWidth() == 0.0 && bnd.getHeight() == 0.0);
}
private static void checkStringWidth(Font font, FontRenderContext frc, String str) {
float width = (float) font.getStringBounds(str.toCharArray(), 0, str.length(), frc).getWidth();
float standard = new TextLayout(str, font, frc).getAdvance();
Assert.assertTrue(Math.abs(width - standard) < 0.1f);
}
private static void checkCalculationStringWidth(Font font, String text) {
AffineTransform affineTransform = new AffineTransform();
Map<TextAttribute, Object> attributes = null;
FontRenderContext frc = new FontRenderContext(affineTransform, true, true);
FontRenderContext baseFrc = new FontRenderContext(new AffineTransform(), true, true);
checkStringWidth(font, frc, text);
checkStringWidth(font.deriveFont(affineTransform), frc, text);
affineTransform.translate(0.5f, 0.0f);
checkStringWidth(font, frc, text);
checkStringWidth(font.deriveFont(affineTransform), baseFrc, text);
attributes = Map.of(TextAttribute.TRACKING, 0.5);
checkStringWidth(font.deriveFont(attributes), baseFrc, text);
attributes = Map.of(TextAttribute.KERNING, TextAttribute.KERNING_ON);
checkStringWidth(font.deriveFont(attributes), baseFrc, text);
attributes = Map.of(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
checkStringWidth(font.deriveFont(attributes), baseFrc, text);
}
@Test
// checking equals of calculation of string's width with two different approach:
// fast implementation inside FontDesignMetrics and guaranteed correct implementation in TextLayout
public void checkCalculationStringWidth() {
final Font font = new Font("Arial", Font.PLAIN, 15);
checkCalculationStringWidth(font,
"AVAVAVAVAVAVAAAAVVAVVAVVVAVAVAVAVAVA !@#$%^&*12345678zc.vbnm.a..s.dfg,hjqwertgyh}{}{}///");
checkCalculationStringWidth(font,
"a");
checkCalculationStringWidth(font,
"世丕且且世两上与丑万丣丕且丗丕");
checkCalculationStringWidth(font,
"\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06\uD83D\uDE06");
}
}