Skip to content

Commit

Permalink
JBR-7237 Fix cyclic dependency of Wayland and Vulkan initialization (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
YaaZ authored and jbrbot committed Aug 31, 2024
1 parent 0c17053 commit c080b0d
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 73 deletions.
69 changes: 69 additions & 0 deletions src/java.desktop/share/classes/sun/java2d/vulkan/VKInstance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 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.
*/

package sun.java2d.vulkan;

import sun.util.logging.PlatformLogger;

import java.security.AccessController;
import java.security.PrivilegedAction;

public class VKInstance {

private static final PlatformLogger log = PlatformLogger.getLogger("sun.java2d.vulkan.VKInstance");
private static Boolean initialized;

private static native boolean initNative(long nativePtr, boolean verbose, int deviceNumber);

public static void init(long nativePtr) {
@SuppressWarnings("removal")
String vulkanOption = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan", ""));
if ("true".equalsIgnoreCase(vulkanOption)) {
@SuppressWarnings("removal")
String deviceNumberOption = AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.deviceNumber", "0"));
int parsedDeviceNumber = 0;
try {
parsedDeviceNumber = Integer.parseInt(deviceNumberOption);
} catch (NumberFormatException e) {
log.warning("Invalid Vulkan device number:" + deviceNumberOption);
}
final int deviceNumber = parsedDeviceNumber;
final boolean verbose = "True".equals(vulkanOption);
System.loadLibrary("awt");
initialized = initNative(nativePtr, verbose, deviceNumber);
} else initialized = false;
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Vulkan rendering enabled: " + (initialized ? "YES" : "NO"));
}
}

public static boolean isVulkanEnabled() {
if (initialized == null) throw new RuntimeException("Vulkan not initialized");
return initialized;
}
}
21 changes: 13 additions & 8 deletions src/java.desktop/share/native/common/java2d/vulkan/VKBase.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,11 @@ static const uint32_t REQUIRED_VULKAN_VERSION = VK_MAKE_API_VERSION(0, 1, 2, 0);
#define MAX_ENABLED_EXTENSIONS 5
#define VALIDATION_LAYER_NAME "VK_LAYER_KHRONOS_validation"
#define COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
extern struct wl_display *wl_display;
#endif

static jboolean verbose;
static jint requestedDeviceNumber = -1;
static VKGraphicsEnvironment* geInstance = NULL;
static void* pVulkanLib = NULL;
#define DEBUG
#define INCLUDE_BYTECODE
#define SHADER_ENTRY(NAME, TYPE) static uint32_t NAME ## _ ## TYPE ## _data[] = {
#define BYTECODE_END };
Expand Down Expand Up @@ -151,12 +147,21 @@ void* vulkanLibProc(VkInstance vkInstance, char* procName) {
return vkProc;
}


jboolean VK_Init(jboolean verb, jint requestedDevice) {
/*
* Class: sun_java2d_vulkan_VKInstance
* Method: init
* Signature: (JZI)Z
*/
JNIEXPORT jboolean JNICALL
Java_sun_java2d_vulkan_VKInstance_initNative(JNIEnv *env, jclass wlge, jlong nativePtr, jboolean verb, jint requestedDevice) {
verbose = verb;
if (VKGE_graphics_environment() == NULL) {
VKGraphicsEnvironment* geInstance = VKGE_graphics_environment();
if (geInstance == NULL) {
return JNI_FALSE;
}
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
geInstance->waylandDisplay = (struct wl_display*) jlong_to_ptr(nativePtr);
#endif
if (!VK_FindDevices()) {
return JNI_FALSE;
}
Expand Down Expand Up @@ -547,7 +552,7 @@ jboolean VK_FindDevices() {
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
VkBool32 presentationSupported =
geInstance->vkGetPhysicalDeviceWaylandPresentationSupportKHR(
geInstance->physicalDevices[i], j, wl_display);
geInstance->physicalDevices[i], j, geInstance->waylandDisplay);
#endif
char logFlags[5] = {
queueFamilies[j].queueFlags & VK_QUEUE_GRAPHICS_BIT ? 'G' : '-',
Expand Down
4 changes: 4 additions & 0 deletions src/java.desktop/share/native/common/java2d/vulkan/VKBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ typedef struct {
VkExtensionProperties* extensions;
VkLayerProperties* layers;

#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
struct wl_display* waylandDisplay;
#endif

PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2;
PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
package sun.awt.wl;

import sun.awt.AWTAccessor;
import sun.java2d.vulkan.VKInstance;
import sun.java2d.vulkan.WLVKGraphicsConfig;

import java.awt.GraphicsConfiguration;
Expand Down Expand Up @@ -99,7 +100,7 @@ void updateConfiguration(String name, int width, int height, int scale) {
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()) {
if (VKInstance.isVulkanEnabled()) {
newDefaultConfig = WLVKGraphicsConfig.getConfig(this, width, height, scale);
newConfigs = new GraphicsConfiguration[1];
newConfigs[0] = newDefaultConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Rectangle;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand All @@ -45,57 +43,22 @@
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;
private static final boolean debugScaleEnabled;
@SuppressWarnings("removal")
private static String vulkanOption =
AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan", ""));

@SuppressWarnings("removal")
private static String vulkanOptionDeviceNumber =
AccessController.doPrivileged(
(PrivilegedAction<String>) () -> System.getProperty("sun.java2d.vulkan.deviceNumber", "0"));

private final Dimension totalDisplayBounds = new Dimension();

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(verboseVulkanStatus, vulkanRequestedDeviceNumber);
}
if (log.isLoggable(Level.FINE)) {
log.fine("Vulkan rendering enabled: " + (vulkanEnabled?"YES":"NO"));
}

debugScaleEnabled = SunGraphicsEnvironment.isUIScaleEnabled() && SunGraphicsEnvironment.getDebugScale() >= 1;

// Make sure the toolkit is loaded because otherwise this GE is going to be empty
WLToolkit.isInitialized();
}

private static native boolean initVKWL(boolean verbose, int deviceNumber);

private WLGraphicsEnvironment() {
}

public static boolean isVulkanEnabled() {
return vulkanEnabled;
}

private static class Holder {
static final WLGraphicsEnvironment INSTANCE = new WLGraphicsEnvironment();
}
Expand Down
6 changes: 4 additions & 2 deletions src/java.desktop/unix/classes/sun/awt/wl/WLToolkit.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import sun.awt.SunToolkit;
import sun.awt.UNIXToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.wl.WLDisplay;
import sun.java2d.vulkan.VKInstance;
import sun.util.logging.PlatformLogger;

import java.awt.*;
Expand Down Expand Up @@ -143,7 +143,9 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
static {
if (!GraphicsEnvironment.isHeadless()) {
keyboard = new WLKeyboard();
initIDs(WLDisplay.getInstance().getDisplayPtr());
long display = WLDisplay.getInstance().getDisplayPtr();
VKInstance.init(display);
initIDs(display);
}
initialized = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Java_sun_java2d_vulkan_WLVKSurfaceData_assignSurface(JNIEnv *env, jobject wsd, j
VKSD_InitWindowSurface(vkwinsdo);
J2dRlsTraceLn(J2D_TRACE_INFO, "WLVKSurfaceData_assignSurface: Created WaylandSurfaceKHR");

J2dTraceLn2(J2D_TRACE_INFO, "WLVKSurfaceData_assignSurface wl_surface(%p) wl_display(%p)", wlSurface, wl_display);
J2dTraceLn2(J2D_TRACE_INFO, "WLVKSurfaceData_assignSurface wl_surface(%p) wl_display(%p)", wlvksdo->wl_surface, wl_display);

#endif /* !HEADLESS */
}
Expand Down
24 changes: 0 additions & 24 deletions src/java.desktop/unix/native/libawt_wlawt/WLGraphicsEnvironment.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

#include "JNIUtilities.h"
#include "WLToolkit.h"
#include "VKInit.h"

typedef struct WLOutput {
struct WLOutput * next;
Expand Down Expand Up @@ -280,27 +279,4 @@ WLOutputByID(uint32_t id)

return NULL;
}

/*
* Class: sun_awt_wl_WLGraphicsEnvironment
* Method: initVKWL
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL
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
BufferedImage.getGraphics()
BufferedImage.createGraphics()
GraphicsEnvironment.getLocalGraphicsEnvironment()
GraphicsEnvironment$LocalGE.createGE()
PlatformGraphicsInfo.createGE()
WLGraphicsEnvironment.initVKWL()
*/
//AWT_LOCK();
vkwlAvailable = VK_Init(verbose, requestedDevice);
//AWT_UNLOCK();
return vkwlAvailable;
}
#endif // #ifndef HEADLESS

0 comments on commit c080b0d

Please sign in to comment.